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"\n"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模塊就支持斷點的功能,使用起來就完美了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM