www.pudn.com > Modbus.rar > csv.cs, change:2013-04-09,size:15550b


using System; 
using System.Collections.Generic; 
//using System.Linq; 
using System.Text; 
using System.Data; 
using System.Collections; 
using System.IO; 
 
namespace Modbus数据采集工具 
{ 
    //读CSV文件类,读取指定的CSV文件,可以导出DataTable 
    public class CsvStreamReader 
    { 
        private ArrayList rowAL;         //行链表,CSV文件的每一行就是一个链 
        private string fileName;        //文件名 
 
        private Encoding encoding;        //编码 
 
        public CsvStreamReader() 
        { 
            this.rowAL = new ArrayList(); 
            this.fileName = ""; 
            this.encoding = Encoding.Default; 
        } 
 
        /// <summary> 
        /// 
        /// </summary> 
        /// <param name="fileName">文件名,包括文件路径</param> 
        public CsvStreamReader(string fileName) 
        { 
            this.rowAL = new ArrayList(); 
            this.fileName = fileName; 
            this.encoding = Encoding.Default; 
            LoadCsvFile(); 
        } 
 
        /// <summary> 
        /// 
        /// </summary> 
        /// <param name="fileName">文件名,包括文件路径</param> 
        /// <param name="encoding">文件编码</param> 
        public CsvStreamReader(string fileName, Encoding encoding) 
        { 
            this.rowAL = new ArrayList(); 
            this.fileName = fileName; 
            this.encoding = encoding; 
            LoadCsvFile(); 
        } 
 
        /// <summary> 
        /// 文件名,包括文件路径 
        /// </summary> 
        public string FileName 
        { 
            set 
            { 
                this.fileName = value; 
                LoadCsvFile(); 
            } 
        } 
 
        /// <summary> 
        /// 文件编码 
        /// </summary> 
 
        public Encoding FileEncoding 
        { 
            set 
            { 
                this.encoding = value; 
            } 
        } 
 
        /// <summary> 
        /// 获取行数 
        /// </summary> 
        public int RowCount 
        { 
            get 
            { 
                return this.rowAL.Count; 
            } 
        } 
 
        /// <summary> 
        /// 获取列数 
        /// </summary> 
        public int ColCount 
        { 
            get 
            { 
                int maxCol; 
 
                maxCol = 0; 
                for (int i = 0; i < this.rowAL.Count; i++) 
                { 
                    ArrayList colAL = (ArrayList)this.rowAL[i]; 
 
                    maxCol = (maxCol > colAL.Count) ? maxCol : colAL.Count; 
                } 
 
                return maxCol; 
            } 
        } 
 
 
        /// <summary> 
        /// 获取某行某列的数据 
 
        /// row:行,row = 1代表第一行 
 
        /// col:列,col = 1代表第一列   
        /// </summary> 
        public string this[int row, int col] 
        { 
            get 
            { 
                //数据有效性验证 
 
                CheckRowValid(row); 
                CheckColValid(col); 
                ArrayList colAL = (ArrayList)this.rowAL[row - 1]; 
 
                //如果请求列数据大于当前行的列时,返回空值 
 
                if (colAL.Count < col) 
                { 
                    return ""; 
                } 
 
                return colAL[col - 1].ToString(); 
            } 
        } 
 
 
        /// <summary> 
        /// 根据最小行,最大行,最小列,最大列,来生成一个DataTable类型的数据 
 
        /// 行等于1代表第一行 
 
        /// 列等于1代表第一列 
 
        /// maxrow: -1代表最大行 
        /// maxcol: -1代表最大列 
        /// </summary> 
        public DataTable this[int minRow, int maxRow, int minCol, int maxCol] 
        { 
            get 
            { 
                //数据有效性验证 
 
                CheckRowValid(minRow); 
                CheckMaxRowValid(maxRow); 
                CheckColValid(minCol); 
                CheckMaxColValid(maxCol); 
                if (maxRow == -1) 
                { 
                    maxRow = RowCount; 
                } 
                if (maxCol == -1) 
                { 
                    maxCol = ColCount; 
                } 
                if (maxRow < minRow) 
                { 
                    throw new Exception("最大行数不能小于最小行数"); 
                } 
                if (maxCol < minCol) 
                { 
                    throw new Exception("最大列数不能小于最小列数"); 
                } 
                DataTable csvDT = new DataTable(); 
                int i; 
                int col; 
                int row; 
 
                //增加列 
 
                for (i = minCol; i <= maxCol; i++) 
                { 
                    csvDT.Columns.Add(i.ToString()); 
                } 
                for (row = minRow; row <= maxRow; row++) 
                { 
                    DataRow csvDR = csvDT.NewRow(); 
 
                    i = 0; 
                    for (col = minCol; col <= maxCol; col++) 
                    { 
                        csvDR[i] = this[row, col]; 
                        i++; 
                    } 
                    csvDT.Rows.Add(csvDR); 
                } 
 
                return csvDT; 
            } 
        } 
 
 
        /// <summary> 
        /// 检查行数是否是有效的 
 
        /// </summary> 
        /// <param name="col"></param>   
        private void CheckRowValid(int row) 
        { 
            if (row <= 0) 
            { 
                throw new Exception("行数不能小于0"); 
            } 
            if (row > RowCount) 
            { 
                throw new Exception("没有当前行的数据"); 
            } 
        } 
 
        /// <summary> 
        /// 检查最大行数是否是有效的 
 
        /// </summary> 
        /// <param name="col"></param>   
        private void CheckMaxRowValid(int maxRow) 
        { 
            if (maxRow <= 0 && maxRow != -1) 
            { 
                throw new Exception("行数不能等于0或小于-1"); 
            } 
            if (maxRow > RowCount) 
            { 
                throw new Exception("没有当前行的数据"); 
            } 
        } 
 
        /// <summary> 
        /// 检查列数是否是有效的 
 
        /// </summary> 
        /// <param name="col"></param>   
        private void CheckColValid(int col) 
        { 
            if (col <= 0) 
            { 
                throw new Exception("列数不能小于0"); 
            } 
            if (col > ColCount) 
            { 
                throw new Exception("没有当前列的数据"); 
            } 
        } 
 
        /// <summary> 
        /// 检查检查最大列数是否是有效的 
 
        /// </summary> 
        /// <param name="col"></param>   
        private void CheckMaxColValid(int maxCol) 
        { 
            if (maxCol <= 0 && maxCol != -1) 
            { 
                throw new Exception("列数不能等于0或小于-1"); 
            } 
            if (maxCol > ColCount) 
            { 
                throw new Exception("没有当前列的数据"); 
            } 
        } 
 
        /// <summary> 
        /// 载入CSV文件 
        /// </summary> 
        private void LoadCsvFile() 
        { 
            //对数据的有效性进行验证 
 
            if (this.fileName == null) 
            { 
                throw new Exception("请指定要载入的CSV文件名"); 
            } 
            else if (!File.Exists(this.fileName)) 
            { 
                throw new Exception("指定的CSV文件不存在"); 
            } 
            else 
            { 
            } 
            if (this.encoding == null) 
            { 
                this.encoding = Encoding.Default; 
            } 
 
            StreamReader sr = new StreamReader(this.fileName, this.encoding); 
            string csvDataLine; 
 
            csvDataLine = ""; 
            while (true) 
            { 
                string fileDataLine; 
 
                fileDataLine = sr.ReadLine(); 
                if (fileDataLine == null) 
                { 
                    break; 
                } 
                if (csvDataLine == "") 
                { 
                    csvDataLine = fileDataLine;//GetDeleteQuotaDataLine(fileDataLine); 
                } 
                else 
                { 
                    csvDataLine += "\r\n" + fileDataLine;//GetDeleteQuotaDataLine(fileDataLine); 
                } 
                //如果包含偶数个引号,说明该行数据中出现回车符或包含逗号 
                if (!IfOddQuota(csvDataLine)) 
                { 
                    AddNewDataLine(csvDataLine); 
                    csvDataLine = ""; 
                } 
            } 
            sr.Close(); 
            //数据行出现奇数个引号 
            if (csvDataLine.Length > 0) 
            { 
                throw new Exception("CSV文件的格式有错误"); 
            } 
        } 
 
        /// <summary> 
        /// 获取两个连续引号变成单个引号的数据行 
        /// </summary> 
        /// <param name="fileDataLine">文件数据行</param> 
        /// <returns></returns> 
        private string GetDeleteQuotaDataLine(string fileDataLine) 
        { 
            return fileDataLine.Replace("\"\"", "\""); 
        } 
 
        /// <summary> 
        /// 判断字符串是否包含奇数个引号 
        /// </summary> 
        /// <param name="dataLine">数据行</param> 
        /// <returns>为奇数时,返回为真;否则返回为假</returns> 
        private bool IfOddQuota(string dataLine) 
        { 
            int quotaCount; 
            bool oddQuota; 
 
            quotaCount = 0; 
            for (int i = 0; i < dataLine.Length; i++) 
            { 
                if (dataLine[i] == '\"') 
                { 
                    quotaCount++; 
                } 
            } 
 
            oddQuota = false; 
            if (quotaCount % 2 == 1) 
            { 
                oddQuota = true; 
            } 
 
            return oddQuota; 
        } 
 
        /// <summary> 
        /// 判断是否以奇数个引号开始 
 
        /// </summary> 
        /// <param name="dataCell"></param> 
        /// <returns></returns> 
        private bool IfOddStartQuota(string dataCell) 
        { 
            int quotaCount; 
            bool oddQuota; 
 
            quotaCount = 0; 
            for (int i = 0; i < dataCell.Length; i++) 
            { 
                if (dataCell[i] == '\"') 
                { 
                    quotaCount++; 
                } 
                else 
                { 
                    break; 
                } 
            } 
 
            oddQuota = false; 
            if (quotaCount % 2 == 1) 
            { 
                oddQuota = true; 
            } 
 
            return oddQuota; 
        } 
 
        /// <summary> 
        /// 判断是否以奇数个引号结尾 
        /// </summary> 
        /// <param name="dataCell"></param> 
        /// <returns></returns> 
        private bool IfOddEndQuota(string dataCell) 
        { 
            int quotaCount; 
            bool oddQuota; 
 
            quotaCount = 0; 
            for (int i = dataCell.Length - 1; i >= 0; i--) 
            { 
                if (dataCell[i] == '\"') 
                { 
                    quotaCount++; 
                } 
                else 
                { 
                    break; 
                } 
            } 
 
            oddQuota = false; 
            if (quotaCount % 2 == 1) 
            { 
                oddQuota = true; 
            } 
 
            return oddQuota; 
        } 
 
        /// <summary> 
        /// 加入新的数据行 
 
        /// </summary> 
        /// <param name="newDataLine">新的数据行</param> 
        private void AddNewDataLine(string newDataLine) 
        { 
            //System.Diagnostics.Debug.WriteLine("NewLine:" + newDataLine); 
 
            ////return; 
 
            ArrayList colAL = new ArrayList(); 
            string[] dataArray = newDataLine.Split(','); 
            bool oddStartQuota;        //是否以奇数个引号开始 
 
            string cellData; 
 
            oddStartQuota = false; 
            cellData = ""; 
            for (int i = 0; i < dataArray.Length; i++) 
            { 
                if (oddStartQuota) 
                { 
                    //因为前面用逗号分割,所以要加上逗号 
                    cellData += "," + dataArray[i]; 
                    //是否以奇数个引号结尾 
                    if (IfOddEndQuota(dataArray[i])) 
                    { 
                        colAL.Add(GetHandleData(cellData)); 
                        oddStartQuota = false; 
                        continue; 
                    } 
                } 
                else 
                { 
                    //是否以奇数个引号开始 
 
                    if (IfOddStartQuota(dataArray[i])) 
                    { 
                        //是否以奇数个引号结尾,不能是一个双引号,并且不是奇数个引号 
 
                        if (IfOddEndQuota(dataArray[i]) && dataArray[i].Length > 2 && !IfOddQuota(dataArray[i])) 
                        { 
                            colAL.Add(GetHandleData(dataArray[i])); 
                            oddStartQuota = false; 
                            continue; 
                        } 
                        else 
                        { 
 
                            oddStartQuota = true; 
                            cellData = dataArray[i]; 
                            continue; 
                        } 
                    } 
                    else 
                    { 
                        colAL.Add(GetHandleData(dataArray[i])); 
                    } 
                } 
            } 
            if (oddStartQuota) 
            { 
                throw new Exception("数据格式有问题"); 
            } 
            this.rowAL.Add(colAL); 
        } 
 
 
        /// <summary> 
        /// 去掉格子的首尾引号,把双引号变成单引号 
 
        /// </summary> 
        /// <param name="fileCellData"></param> 
        /// <returns></returns> 
        private string GetHandleData(string fileCellData) 
        { 
            if (fileCellData == "") 
            { 
                return ""; 
            } 
            if (IfOddStartQuota(fileCellData)) 
            { 
                if (IfOddEndQuota(fileCellData)) 
                { 
                    return fileCellData.Substring(1, fileCellData.Length - 2).Replace("\"\"", "\""); //去掉首尾引号,然后把双引号变成单引号 
                } 
                else 
                { 
                    throw new Exception("数据引号无法匹配" + fileCellData); 
                } 
            } 
            else 
            { 
                //考虑形如""    """"      """"""    
                if (fileCellData.Length > 2 && fileCellData[0] == '\"') 
                { 
                    fileCellData = fileCellData.Substring(1, fileCellData.Length - 2).Replace("\"\"", "\""); //去掉首尾引号,然后把双引号变成单引号 
                } 
            } 
 
            return fileCellData; 
        } 
    } 
}