zoukankan      html  css  js  c++  java
  • C#对.CSV格式的文件--逗号分隔值文件 的读写操作及上传ftp服务器操作方法总结

    前言 

    公司最近开发需要将数据保存到.csv文件(逗号分隔值 文件)中然后上传到ftp服务器上,供我们系统还有客户系统调用,之前完全没有接触过这个,所以先来看看百度的解释:逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须像二进制数字那样被解读的数据。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。通常,所有记录都有完全相同的字段序列。

    CSV文件格式的通用标准并不存在,但是在RFC 4180中有基础性的描述。使用的字符编码同样没有被指定,但是7-bitASCII是最基本的通用编码。

    简单的说就是逗号隔开 双引号 内即为吗需要的值 数据格式并没有非常统一的标准 但是为了避免出错 我们在开发的时候统一格式是这样的

    "name","pwd","date"

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

    接下来代码处理中默认格式都是这样的 其实就是纯文本的形式

    为什么要用csv文件

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

    而在项目开发中 有需要做的处理也不是很简单的

    比如有csv文件的读取 数据的转换(如转成datatable),csv文件的重命名 ,csv文件的写入,文件上传到ftp服务器上等等

    这里将开发的方法进行了简单的整理,以备不时之需,时间仓促,有不足之处大家多多指点。

    注意的点

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

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

    ③文件末尾不能出现空的行,不然会出现datatable溢出情况,这种情况可以代码处理 但是开发中最好约束好方便数据处理

    一、将CSV文件的数据读取到DataTable中

    首先,我们为了方便管理,在web网站中常常需要读取csv文件中的数据并且显示在网站上方便查询。所以比较方便的办法是见csv文件中的数据转换成datatable形式,代码如下。

    /// <summary>
    /// 将CSV文件的数据读取到DataTable中
    /// </summary>
    /// <param name="fileName">CSV文件路径</param>
    /// <returns>返回读取了CSV数据的DataTable</returns>
    public static DataTable OpenCSV(string filePath)
    {
        DataTable dt = new DataTable();
        FileStream fs = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
    
        StreamReader sr = new StreamReader(fs, Encoding.UTF8);
        //StreamReader sr = new StreamReader(fs, encoding);
        //string fileContent = sr.ReadToEnd();
        //记录每次读取的一行记录
        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++)
                {
                    tableHead[i] = tableHead[i].Replace(""", "");
                    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].Replace(""","");
                }
                dt.Rows.Add(dr);
            }
        }
        if (aryLine != null && aryLine.Length > 0)
        {
            dt.DefaultView.Sort = tableHead[2] + " " + "DESC";
        }
    
        sr.Close();
        fs.Close();
        return dt;
    }

    二、将DataTable中数据写入到CSV文件中

     当然我们一个文件中的数据迁移到另一个文件中或者 直接从数据库中查询的数据 插入到csv文件中 ,有一种方法是通过datatable的形式中转,所以 需要把datatable 转成 csv 代码如下:

    /// <summary>
    /// 将DataTable中数据写入到CSV文件中
    /// </summary>
    /// <param name="dt">提供保存数据的DataTable</param>
    /// <param name="fileName">CSV的文件路径</param>
    public static bool SaveCSV(DataTable dt, string fullPath)
    {
        try
        {
            FileInfo fi = new FileInfo(fullPath);
            if (!fi.Directory.Exists)
            {
                fi.Directory.Create();
            }
            FileStream fs = new FileStream(fullPath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
            //StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.Default);
            StreamWriter sw = new 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 = string.Format(""{0}"", str);
                    data += str;
                    if (j < dt.Columns.Count - 1)
                    {
                        data += ",";
                    }
                }
                sw.WriteLine(data);
            }
            sw.Close();
            fs.Close();
            return true;
        }
        catch {
            return false;
        }
    }

    三、修改文件名称 

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

    /// <summary>
    /// 修改文件名称 
    /// </summary>
    /// <param name="OldPath">旧的路径 完整的物理路径</param>
    /// <param name="NewPath">新的路径</param>
    /// <returns></returns>
    public static bool ChangeFileName(string OldPath, string NewPath) {
        bool re = false;
        //OldPath = HttpContext.Current.Server.MapPath(OldPath);虚拟的
        //NewPath = HttpContext.Current.Server.MapPath(NewPath);
        try {
            if (File.Exists(OldPath)) {
                File.Move(OldPath, NewPath);
                re = true;
            }
        }
        catch {
            re = false;
        }
        return re;
    }

    四、scv文件的数据写入

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

     1 /// <summary>
     2 /// 写入文件
     3 /// </summary>
     4 /// <param name="fullPath"></param>
     5 /// <param name="Data"></param>
     6 /// <returns></returns>
     7 public static bool SaveCSV(string fullPath,string Data)
     8 {
     9     bool re = true;
    10     try
    11     {
    12         FileStream FileStream = new FileStream(fullPath, FileMode.Append);
    13         StreamWriter sw = new StreamWriter(FileStream, System.Text.Encoding.UTF8);
    14         sw.WriteLine(Data);
    15         //清空缓冲区
    16         sw.Flush();
    17         //关闭流
    18         sw.Close();
    19         FileStream.Close();
    20     }
    21     catch {
    22         re = false;
    23     }
    24     return re;
    25 }

     五、上传到ftp服务器

    把处理好的数据文件上传到ftp服务器供系统调用

    /// <summary>
    /// 上传文件
    /// </summary>
    /// <param name="fileinfo">需要上传的文件</param>
    /// <param name="targetDir">目标路径</param>
    /// <param name="hostname">ftp地址(不带ftp;//)</param>
    /// <param name="username">ftp用户名</param>
    /// <param name="password">ftp密码</param>
    public static bool UploadFtpFile(FileInfo fileinfo, string targetDir, string hostname, string username, string password)
    {
        bool re = true;
        //1. check target
        string target;
        if (targetDir.Trim() == "")
        {
            return false;
        }
        target = fileinfo.Name;  //使用临时文件名
                
    
        string URI = "FTP://" + hostname + "/" + targetDir + "/" + target;
        ///WebClient webcl = new WebClient();
        System.Net.FtpWebRequest ftp = GetRequest(URI, username, password);
    
        //设置FTP命令 设置所要执行的FTP命令,
        //ftp.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails;//假设此处为显示指定路径下的文件列表
        ftp.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
        //指定文件传输的数据类型
        ftp.UseBinary = true;
        ftp.UsePassive = true;
    
        //告诉ftp文件大小
        ftp.ContentLength = fileinfo.Length;
        //缓冲大小设置为2KB
        const int BufferSize = 2048;
        byte[] content = new byte[BufferSize - 1 + 1];
        int dataRead;
    
        //打开一个文件流 (System.IO.FileStream) 去读上传的文件
        using (FileStream fs = fileinfo.OpenRead())
        {
            try
            {
                //把上传的文件写入流
                using (Stream rs = ftp.GetRequestStream())
                {
                    do
                    {
                        //每次读文件流的2KB
                        dataRead = fs.Read(content, 0, BufferSize);
                        rs.Write(content, 0, dataRead);
                    } while (!(dataRead < BufferSize));
                    rs.Close();
                }
    
            }
            catch (Exception ex) {
                re = false;
    
            }
            finally
            {
                fs.Close();
            }
        }
        return re;
    }

    本文版权归作者(谢俊)和博客园所有,欢迎转载,转载请标明出处。

    原文地址:http://www.cnblogs.com/net-xiejun/

    微信开发群C#.NETWEB程序开发交流

    完整源码下载:https://github.com/xiejun-net/weixin

    公众账号:

  • 相关阅读:
    mescroll vue tab页实现切换刷新列表
    路由权限配置
    js实现拖拽
    .eslintrc.js
    vue-cli项目中使用mock结合axios-mock-adapter生成模拟数据【转】
    原型模式
    设计模式简介
    @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
    spring定时任务执行两次
    java反射--注解的定义与运用以及权限拦截
  • 原文地址:https://www.cnblogs.com/net-xiejun/p/4847221.html
Copyright © 2011-2022 走看看