完整的读写csv文件的类

1.读csv的类

代码
public class CsvStreamReader
    {
        
private ArrayList rowAL;       
        
private string fileName;       
        
private Encoding encoding;  
        
public CsvStreamReader()
        {
            
this.rowAL = new ArrayList();
            
this.fileName = "";
            
this.encoding = Encoding.Default;
        }
        
public CsvStreamReader(string fileName)
        {
            
this.rowAL = new ArrayList();
            
this.fileName = fileName;
            
this.encoding = Encoding.Default;
            LoadCsvFile();
        }
        
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 string.Empty;

                
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文件不存在");

            
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)
        {
            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;
        }
    }

2.写csv文件的类

代码
public class CsvStreamWriter
    {
        
private ArrayList rowAL;
        
private string fileName;
        
private Encoding encoding;

        
public CsvStreamWriter()
        {
            
this.rowAL = new ArrayList();
            
this.fileName = "";
            
this.encoding = Encoding.Default;
        }
        
public CsvStreamWriter(string fileName)
        {
            
this.rowAL = new ArrayList();
            
this.fileName = fileName;
            
this.encoding = Encoding.Default;
        }
        
public CsvStreamWriter(string fileName, Encoding encoding)
        {
            
this.rowAL = new ArrayList();
            
this.fileName = fileName;
            
this.encoding = encoding;
        }

        
/// <summary>
        
/// row:行,row = 1代表第一行
        
/// col:列,col = 1代表第一列
        
/// </summary>
        public string this[int row, int col]
        {
            
set
            {
                
if (row <= 0)
                    
throw new Exception("行数不能小于0");
                
else if (row > this.rowAL.Count)
                {
                    
for (int i = this.rowAL.Count + 1; i <= row; i++)
                        
this.rowAL.Add(new ArrayList());
                }
                
if (col <= 0)
                    
throw new Exception("列数不能小于0");
                
else
                {
                    ArrayList colTempAL 
= (ArrayList)this.rowAL[row - 1];
                    
if (col > colTempAL.Count)
                    {
                        
for (int i = colTempAL.Count; i <= col; i++)
                            colTempAL.Add(
"");
                    }
                    
this.rowAL[row - 1= colTempAL;
                }
                ArrayList colAL 
= (ArrayList)this.rowAL[row - 1];
                colAL[col 
- 1= value;
                
this.rowAL[row - 1= colAL;
            }
        }
        
/// <summary>
        
/// 文件名,包括文件路径
        
/// </summary>
        public string FileName
        {
            
set { this.fileName = value; }
        }
        
/// <summary>
        
/// 文件编码
        
/// </summary>
        public Encoding FileEncoding
        {
            
set { this.encoding = value; }
        }
        
/// <summary>
        
/// 获取当前最大行
        
/// </summary>
        public int CurMaxRow
        {
            
get { return this.rowAL.Count; }
        }
        
/// <summary>
        
/// 获取最大列
        
/// </summary>
        public int CurMaxCol
        {
            
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>
        
/// 添加表数据到CSV文件中
        
/// </summary>
        
/// <param name="dataDT">表数据</param>
        
/// <param name="beginCol">从第几列开始,beginCol = 1代表第一列</param>
        public void AddData(DataTable dataDT, int beginCol)
        {
            
if (dataDT == null)
                
throw new Exception("需要添加的表数据为空");
            
int curMaxRow;

            curMaxRow 
= this.rowAL.Count;
            
for (int i = 0; i < dataDT.Rows.Count; i++)
            {
                
for (int j = 0; j < dataDT.Columns.Count; j++)
                {
                    
this[curMaxRow + i + 1, beginCol + j] = dataDT.Rows[i][j].ToString();
                }
            }
        }
        
/// <summary>
        
/// 保存数据,如果当前硬盘中已经存在文件名一样的文件,将会覆盖
        
/// </summary>
        public void Save()
        {
            
//对数据的有效性进行判断
            if (this.fileName == null)
                
throw new Exception("缺少文件名");
            
else if (File.Exists(this.fileName))
                File.Delete(
this.fileName);

            
if (this.encoding == null)
                
this.encoding = Encoding.Default;

            System.IO.StreamWriter sw 
= new StreamWriter(this.fileName, falsethis.encoding);
            
for (int i = 0; i < this.rowAL.Count; i++)
                sw.WriteLine(ConvertToSaveLine((ArrayList)
this.rowAL[i]));

            sw.Close();
        }
        
/// <summary>
        
/// 保存数据,如果当前硬盘中已经存在文件名一样的文件,将会覆盖
        
/// </summary>
        
/// <param name="fileName">文件名,包括文件路径</param>
        public void Save(string fileName)
        {
            
this.fileName = fileName;
            Save();
        }
        
/// <summary>
        
/// 保存数据,如果当前硬盘中已经存在文件名一样的文件,将会覆盖
        
/// </summary>
        
/// <param name="fileName">文件名,包括文件路径</param>
        
/// <param name="encoding">文件编码</param>
        public void Save(string fileName, Encoding encoding)
        {

            
this.fileName = fileName;
            
this.encoding = encoding;
            Save();
        }
        
/// <summary>
        
/// 转换成保存行
        
/// </summary>
        
/// <param name="colAL">一行</param>
        
/// <returns></returns>
        private string ConvertToSaveLine(ArrayList colAL)
        {
            
string saveLine;

            saveLine 
= "";
            
for (int i = 0; i < colAL.Count; i++)
            {
                saveLine 
+= colAL[i].ToString();
                
//格子间以逗号分割
                if (i < colAL.Count - 1)
                    saveLine 
+= ",";
            }

            
return saveLine;
        }
        
/// <summary>
        
/// 字符串转换成CSV中的格子
        
/// 双引号转换成两个双引号,然后首尾各加一个双引号
        
/// 这样就不需要考虑逗号及换行的问题
        
/// </summary>
        
/// <param name="cell">格子内容</param>
        
/// <returns></returns>
        //private string ConvertToSaveCell(string cell)
        
//{
        
// cell = cell.Replace("\"","\"\"");

        
// return "\"" + cell + "\"";
        
//}
    }

使用实例:

代码
    private void button1_Click(object sender, EventArgs e)
        {
            CsvStreamReader csvr 
= new CsvStreamReader("c:\\epdev_list.txt");
            CsvStreamWriter csvw 
= new CsvStreamWriter("c:\\epdev_list.txt");


            
for (int i = 0; i < 26; i++)
            {
                csvw[i 
+ 11= csvr[i + 11];
                csvw[i 
+ 12= csvr[i + 12];
                csvw[i 
+ 13= (Environment.TickCount / 1000).ToString();
                csvw[i 
+ 14= csvr[i + 14];
                csvw[i 
+ 15= csvr[i + 15];
                csvw[i 
+ 16= csvr[i + 16];
                csvw[i 
+ 17= csvr[i + 17];
                csvw[i 
+ 18= csvr[i + 18];
                csvw[i 
+ 19= csvr[i + 19];
                csvw[i 
+ 110= csvr[i + 110];
            }
            csvw.Save();
        }
原文地址:https://www.cnblogs.com/kakaliush/p/1933002.html