zoukankan      html  css  js  c++  java
  • nodejs:csv模块解析

     Nodejs最大的特点就是基于事件驱动和异步并发操作。大多数人知道nodejs是用于网络后台服务的新平台,可以很方便的提供后台服务;除了用于网络开发外,其实nodejs对于线下文件并发处理也是很方便的,不同于C++java,利用nodejs可以快速的搭建读写框架,实现文件处理操作。

             本文介绍一种程序开发中常见文件格式(csv)的处理。在nodejs官网提供的开发包中,有很多关于csv的包,下载量最多的是CSV包,下面就介绍如何使用CSV包处理文件。

    首先下载包:

    npm install csv

    以官网上的例子解析用法:

     

    //node samples/string.js
    var csv =require('csv');
    csv()

    .from('"1","2","3","4" "a","b","c","d"')

    .to(console.log )
    //Output:

    //1,2,3,4
    //a,b,c,d

     

        首先要引用csv模块,require('csv'),引用之后,它封装的方法和属性就可以直接使用了。csv()相当于实例化一个对象,.from.to都是csv封装的方法

    .from()方法:顾名思义,是从源文件中读取数据,参数既可以像上面一样直接传字符串,也可以像下面的高级应用传源文件的路径。

    .to()方法:是将从form方法中读取出的数据输出,既可以输出到控制台,也可以输出到目标文件。此例子是输出到控制台。

     

     1 // node samples/sample.js
     2 var fs =require('fs');
     3 var csv =require('csv');
     4 csv()
     5 .from.stream(fs.createReadStream(__dirname+'/sample.in'))
     6 .to.path(__dirname+'/sample.out')
     7 .transform(function(row){
     8 row.unshift(row.pop());
     9 return row;
    10 })
    11 .on('record',function(row,index){
    12 console.log('#'+index+' '+JSON.stringify(row));
    13 })
    14 .on('close',function(count){
    15 // when writing to a file, use the 'close' event
    16 // the 'end' event may fire before the file has been written
    17 console.log('Number of lines: '+count);
    18 })
    19 .on('error',function(error){
    20 console.log(error.message);
    21 });
    22 // Output:
    23 // #0 ["2000-01-01","20322051544","1979.0","8.8017226E7","ABC","45"]
    24 // #1 ["2050-11-27","28392898392","1974.0","8.8392926E7","DEF","23"]
    25 // Number of lines: 2

     

     

    .transform()方法:处理from读取出的数据,处理后写入到目标文件;参数可以传回调函数,在回调函数中,可以写处理数据的方法。

    .on() : 事件监听机制,

    'record'监听读取出的每行记录,参数中row是一行的数据,index是数据个数,注意,此数据个数只是读取出的数据个数,而不是处理完的数据个数,因为nodejs是异步操作,所以处理数据是批量的,程序会一批批的将数据发出给transform,等到处理完一批后再写入目标文件,因而读取出的个数index往往大于已经写入文件的个数,关于如何捕获处理完写入文件的个数,后面会进行处理。

    'end' 处理完一个文件后触发的事件;

    'error' 处理数据时,发生异常触发的事件;

    'close'文件关闭时触发的事件;

     

    高级用法:

             csv模块的高级之处在于它按行读取数据,读取出来的数据是以对象的形式,列名是对象的key,值是value,这样取每一列的值就变得非常简单,不想c++中那样还得解析字段。

    .from.path(strSrcPath, {header: true, columns: true})

    from方法中第二个参数设置将列分开;

    在将处理后的数据写入新的文件时,也可以设置参数。

            .to.path(strDestPath,{

                header: true

                ,lineBreaks:'windows'

                ,newColumns: true

                ,end: false

                ,columns:fields

                ,flags : 'w'

            })

     

    下面是每个参数的说明

           *   `delimiter`   csv文件每列的分隔符;

    *   `columns`    目标文件目标文件的列,

    *   `header`     是否带有表头;

          *    `lineBreaks`  分隔行之间的标识,有 'auto', 'unix', 'mac', 'windows', 'unicode'几种;

          *   `flags`       新建目标文件还是在已有的目标文件上追加数据,’w’新建;’a’追加;

          *   `end`        在响应end消息之前,文件不可写;

     

    csv断点续传

             csv模块唯一的缺陷就是不能支持断点,即一个文件没有处理完,下次接着处理。解决此问题的关键在于要捕获到程序已经处理数据的个数,前面提到'record'只能监听到程序读取到的个数,而不代表已经写入文件的个数。跟踪了csv模块的源代码,发现只要修改源代码,监听到每次批量写入目标文件时的事件,问题就迎刃而解。

    this.emit("writen", this.state.countWriten);

    在csv.js添加自定义的监听事件,countWriten就是记录的每次写入目标文件的个数。然后在调用csv模块时添加上此事件即可。

            .on('writen', function(index){

                console.log("rtn", index);

            })

    这样就能实时捕获到写入文件的个数,可以将此数据写入游标文件记录下来。稍加修改,csv模块就支持断点的功能,使用起来就完美了。

  • 相关阅读:
    B.Icebound and Sequence
    Educational Codeforces Round 65 (Rated for Div. 2) D. Bicolored RBS
    Educational Codeforces Round 65 (Rated for Div. 2) C. News Distribution
    Educational Codeforces Round 65 (Rated for Div. 2) B. Lost Numbers
    Educational Codeforces Round 65 (Rated for Div. 2) A. Telephone Number
    Codeforces Round #561 (Div. 2) C. A Tale of Two Lands
    Codeforces Round #561 (Div. 2) B. All the Vowels Please
    Codeforces Round #561 (Div. 2) A. Silent Classroom
    HDU-2119-Matrix(最大匹配)
    读书的感想!
  • 原文地址:https://www.cnblogs.com/cjingzm/p/3196424.html
Copyright © 2011-2022 走看看