C# CSV文件读写的实现

作者:xgf415 时间:2023-05-24 10:39:07 

CSV是一种通用的、相对简单的文件格式,最广泛的应用是在程序之间转移表格数据,而这些程序本身是在不兼容的格式上进行操作的。那么,C#如何读取和写入csv格式文件呢?CSV数据格式并没有非常统一的标准 但是为了避免出错 我们在开发的时候统一格式是这样的:

"name","pwd","date"

"张三","123","2015-09-30"

接下来代码处理中默认格式都是这样的

为什么要用csv文件

这就涉及到数据互通的问题,有些程序支持的表格数据另一些程序并不见得支持,而csv格式的却被大多数的应用程序支持,所以在交换保存数据的时候是个不错的选择。

注意的点:

  • 文件处理完的时候一定记得关闭释放数据流 否则文件会被占用

  • csv并没有严格的标准,多人开发的时候必须规定好格式,统一开发 

一、DataTable数据写入CSV文件

public static void SaveCSV(DataTable dt, string fullPath)//table数据写入csv
{
   System.IO.FileInfo fi = new System.IO.FileInfo(fullPath);
   if (!fi.Directory.Exists)
   {
       fi.Directory.Create();
   }
   System.IO.FileStream fs = new System.IO.FileStream(fullPath, System.IO.FileMode.Create,
       System.IO.FileAccess.Write);
   System.IO.StreamWriter sw = new System.IO.StreamWriter(fs, System.Text.Encoding.UTF8);
   string data = "";

for (int i = 0; i < dt.Columns.Count; i++)//写入列名
   {
       data += dt.Columns[i].ColumnName.ToString();
       if (i < dt.Columns.Count - 1)
       {
           data += ",";
       }
   }
   sw.WriteLine(data);

for (int i = 0; i < dt.Rows.Count; i++) //写入各行数据
   {
       data = "";
       for (int j = 0; j < dt.Columns.Count; j++)
       {
           string str = dt.Rows[i][j].ToString();
           str = str.Replace("\"", "\"\"");//替换英文冒号 英文冒号需要换成两个冒号
           if (str.Contains(',') || str.Contains('"')
               || str.Contains('\r') || str.Contains('\n')) //含逗号 冒号 换行符的需要放到引号中
           {
               str = string.Format("\"{0}\"", str);
           }

data += str;
           if (j < dt.Columns.Count - 1)
           {
               data += ",";
           }
       }
       sw.WriteLine(data);
   }
   sw.Close();
   fs.Close();
}

二、读取CSV文件到DataTable

public static DataTable OpenCSV(string filePath)//从csv读取数据返回table
{
   System.Text.Encoding encoding = GetType(filePath); //Encoding.ASCII;//
   DataTable dt = new DataTable();
   System.IO.FileStream fs = new System.IO.FileStream(filePath, System.IO.FileMode.Open,
       System.IO.FileAccess.Read);

System.IO.StreamReader sr = new System.IO.StreamReader(fs, encoding);

//记录每次读取的一行记录
   string strLine = "";
   //记录每行记录中的各字段内容
   string[] aryLine = null;
   string[] tableHead = null;
   //标示列数
   int columnCount = 0;
   //标示是否是读取的第一行
   bool IsFirst = true;
   //逐行读取CSV中的数据
   while ((strLine = sr.ReadLine()) != null)
   {
       if (IsFirst == true)
       {
           tableHead = strLine.Split(',');
           IsFirst = false;
           columnCount = tableHead.Length;
           //创建列
           for (int i = 0; i < columnCount; i++)
           {
               DataColumn dc = new DataColumn(tableHead[i]);
               dt.Columns.Add(dc);
           }
       }
       else
       {
           aryLine = strLine.Split(',');
           DataRow dr = dt.NewRow();
           for (int j = 0; j < columnCount; j++)
           {
               dr[j] = aryLine[j];
           }
           dt.Rows.Add(dr);
       }
   }
   if (aryLine != null && aryLine.Length > 0)
   {
       dt.DefaultView.Sort = tableHead[0] + " " + "asc";
   }

sr.Close();
   fs.Close();
   return dt;
}
/// 给定文件的路径,读取文件的二进制数据,判断文件的编码类型
/// <param name="FILE_NAME">文件路径</param>
/// <returns>文件的编码类型</returns>

public static System.Text.Encoding GetType(string FILE_NAME)
{
   System.IO.FileStream fs = new System.IO.FileStream(FILE_NAME, System.IO.FileMode.Open,
       System.IO.FileAccess.Read);
   System.Text.Encoding r = GetType(fs);
   fs.Close();
   return r;
}

/// 通过给定的文件流,判断文件的编码类型
/// <param name="fs">文件流</param>
/// <returns>文件的编码类型</returns>
public static System.Text.Encoding GetType(System.IO.FileStream fs)
{
   byte[] Unicode = new byte[] { 0xFF, 0xFE, 0x41 };
   byte[] UnicodeBIG = new byte[] { 0xFE, 0xFF, 0x00 };
   byte[] UTF8 = new byte[] { 0xEF, 0xBB, 0xBF }; //带BOM
   System.Text.Encoding reVal = System.Text.Encoding.Default;

System.IO.BinaryReader r = new System.IO.BinaryReader(fs, System.Text.Encoding.Default);
   int i;
   int.TryParse(fs.Length.ToString(), out i);
   byte[] ss = r.ReadBytes(i);
   if (IsUTF8Bytes(ss) || (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF))
   {
       reVal = System.Text.Encoding.UTF8;
   }
   else if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00)
   {
       reVal = System.Text.Encoding.BigEndianUnicode;
   }
   else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41)
   {
       reVal = System.Text.Encoding.Unicode;
   }
   r.Close();
   return reVal;
}

/// 判断是否是不带 BOM 的 UTF8 格式
/// <param name="data"></param>
/// <returns></returns>
private static bool IsUTF8Bytes(byte[] data)
{
   int charByteCounter = 1; //计算当前正分析的字符应还有的字节数
   byte curByte; //当前分析的字节.
   for (int i = 0; i < data.Length; i++)
   {
       curByte = data[i];
       if (charByteCounter == 1)
       {
           if (curByte >= 0x80)
           {
               //判断当前
               while (((curByte <<= 1) & 0x80) != 0)
               {
                   charByteCounter++;
               }
               //标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X
               if (charByteCounter == 1 || charByteCounter > 6)
               {
                   return false;
               }
           }
       }
       else
       {
           //若是UTF-8 此时第一位必须为1
           if ((curByte & 0xC0) != 0x80)
           {
               return false;
           }
           charByteCounter--;
       }
   }
   if (charByteCounter > 1)
   {
       throw new Exception("非预期的byte格式");
   }
   return true;
}

三、修改文件名称

我们需要保存历史数据 或者实时的知道那个文件被修改 可以通过改变文件的名称 如加上当天的日期等等。

public static bool ChangeFileName(string OldPath, string NewPath)
{
   bool re = false;
   try
   {
       if (File.Exists(OldPath))
       {
           File.Move(OldPath, NewPath);
           re = true;
       }
   }
   catch
   {
       re = false;
   }
   return re;
}

四、CSV文件的数据写入

直接在网页表单提交数据保存在csv文件中 直接写入文件

public static bool SaveCSV(string fullPath,string Data)
{
   bool re = true;
   try
   {
       FileStream FileStream = new FileStream(fullPath, FileMode.Append);
       StreamWriter sw = new StreamWriter(FileStream, System.Text.Encoding.UTF8);
       sw.WriteLine(Data);
       //清空缓冲区
       sw.Flush();
       //关闭流
       sw.Close();
       FileStream.Close();
   }
   catch
   {
       re = false;
   }
   return re;
}

来源:https://blog.csdn.net/xgf415/article/details/51366877

标签:C#,CSV,文件读写
0
投稿

猜你喜欢

  • Android自定义view实现圆环效果实例代码

    2022-05-22 10:17:25
  • android Service基础(启动服务与绑定服务)

    2023-05-07 12:31:34
  • Java源码解析之ClassLoader

    2022-06-14 06:07:47
  • Java读写文件,在文件中搜索内容,并输出含有该内容的所有行方式

    2022-12-14 18:23:58
  • Java如何读取jar包中的resource资源文件

    2022-10-12 22:51:43
  • Java毕业设计实战之二手书商城系统的实现

    2022-03-21 14:06:20
  • Java关于IO流的全面介绍

    2023-08-12 08:14:46
  • 如何使用SpringSecurity保护程序安全

    2022-09-08 19:57:50
  • java常用工具类之DES和Base64加密解密类

    2023-12-20 17:48:31
  • Java Pattern和Matcher字符匹配方式

    2022-06-07 21:57:56
  • springboot 自定义启动器的实现

    2021-06-05 00:33:14
  • C#中的委托、事件学习笔记

    2023-01-21 18:03:49
  • Java设计模式中代理模式应用详解

    2021-10-06 10:50:56
  • 解析java中super的用法分析

    2021-11-17 19:39:52
  • Java 自定义Spring框架以及Spring框架的基本使用

    2021-05-29 19:35:57
  • C# Winform 实现控件自适应父容器大小的示例代码

    2021-06-15 20:00:52
  • 详细解读Android系统中的application标签

    2021-07-10 02:29:46
  • java Stream流常见操作方法(反射,类加载器,类加载,反射)

    2022-03-24 06:54:56
  • java实现分页显示效果

    2021-12-29 20:17:43
  • springboot连接不上redis的三种解决办法

    2022-03-21 20:57:23
  • asp之家 软件编程 m.aspxhome.com