nl_tokens: read file by specified amount of lines parse head line perfect for CSV - like data files
pl_tokens: function fileLineReader ( filepath , opts ) { if ( typeof arguments [ 0 ] !== 'string' ) { opts = arguments [ 0 ] ; filepath = opts . file || opts . filename || opts . filepath ; } filepath = resolve ( filepath ) . fullPath ; opts = opts || { } ; var chunkSize = opts . chunkSize || 1 ; var hasHeader = opts . header || opts . headers || opts . hasHeader ; var headLine ; var instream = fs . createReadStream ( filepath , opts ) ; var outstream = new Stream ( ) ; var rl = readline . createInterface ( instream , outstream ) ; var onData ; var done ; instream . on ( 'error' , function ( err ) { rl . closed = true ; rl . close ( ) ; if ( done ) done ( err ) ; else throw err ; } ) ; opts . separator = opts . separator || opts . delimiter ; var lineParser = opts . lineParser || function ( line ) { if ( ! opts . separator ) return line ; return line . split ( opts . separator ) ; } ; var lines = [ ] ; var lineError ; var index = - 1 ; var limit = 1 ; function getLines ( numOfLines , cb ) { if ( arguments . length === 0 ) cb = arguments [ 0 ] ; if ( typeof cb !== 'function' ) throw new Error ( 'Wrong arguments' ) ; done = cb ; index = index === - 1 ? - 1 : 0 ; limit = numOfLines || 1 ; var result ; if ( lines . length === 0 ) index = - 1 ; // fix - when paused on chunkSize if ( lines . length >= limit ) { result = <mask> . slice ( 0 , limit ) ; lines . splice ( 0 , limit ) ; return cb ( null , result ) ; } if ( rl . closed ) { result = lines . slice ( ) ; lines = [ ] ; return cb ( null , result ) ; } onData = cb ; rl . resume ( ) ; } rl . on ( 'line' , function ( line ) { index ++ ; line = lineParser ( line ) ; if ( headLine ) { var lineWithHeader = { } ; for ( var i = 0 ; i < headLine . length ; i ++ ) { lineWithHeader [ headLine [ i ] ] = line [ i ] ; } line = lineWithHeader ; } else if ( index === 0 && hasHeader ) { headLine = line ; index -- ; return ; } lines . push ( line ) ; if ( limit <= index + 1 ) { if ( onData ) { rl . pause ( ) ; var result = lines . slice ( 0 , limit ) ; lines . splice ( 0 , limit ) ; onData ( null , result ) ; onData = null ; } } } ) ; rl . on ( 'close' , function ( ) { rl . closed = true ; if ( onData ) { onData ( null , lines ) ; onData = null ; } } ) ; rl . pause ( ) ; return { read : getLines , close : function ( ) { rl . close ( ) ; } } ; }