diff --git a/README.md b/README.md index d2b7bee..1209ba2 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,9 @@ [![Linux Build][travis-image]][travis-url] [![Windows Build][appveyor-image]][appveyor-url] [![Coverage Status][coveralls-image]][coveralls-url] - [![license MIT][license-image]][license-url] [![Dependencies][dependencies-image]][dependencies-url] + [![node][node-image]][node-url] + [![license MIT][license-image]][license-url] ## 安装 @@ -29,20 +30,22 @@ var readLine = require('fs-readline'); var rl = readLine('./somefile.txt'); rl.on('line', function (line, idx) { - console.log(idx, line.toString()); + console.log(idx, line); }); ``` ## 编码处理 -node 支持的编码非常有限, 对于那些不支持的编码可以使用一些第三方库转换, 例如 [iconv-lite][iconv-lite] 模块. +node 支持的编码非常有限, 对于那些不支持的编码可以使用一些第三方库转换, 例如 [iconv-lite][iconv-lite] 模块。 + +> PS: 记得加 `retainBuffer` 参数防止默认 `toString` 哦。 ``` js var readLine = require('fs-readline'); var iconv = require('iconv-lite'); -var rl = readline('./gbkfile.txt'); +var rl = readline('./gbkfile.txt', {retainBuffer: true}); // buffer 模式 rl.on('line', function (data, idx){ var line = iconv.decode(data, 'gbk'); console.log(idx, line); @@ -52,7 +55,21 @@ rl.on('line', function (data, idx){ ## 参数说明 -仅仅只有 2 个附加参数,其他参数继承自 `fs.createReadStream` 参数。 +仅仅只有 4 个附加参数,其他参数继承自 `fs.createReadStream` 参数。 + + +### retainBuffer + +> 是否保留 Buffer 数据,而不是转为字符串,默认 false 转为字符串。 + +``` js +var readLine = require('fs-readline'); + +var rl = readLine('./somefile.txt', {retainBuffer: true}); // buffer 模式 +rl.on('line', function (data, idx) { + console.log(idx, data.toString()); // 这里要手动 toString +}); +``` ### blankLine @@ -75,7 +92,7 @@ var readLine = require('fs-readline'); var rl = readLine('./file.txt', {blankLine: false}); rl.on('line', function (line, idx) { - console.log(idx, line.toString()); + console.log(idx, line); }); // 输出为: @@ -89,7 +106,43 @@ rl.on('line', function (line, idx) { ### maxLineLength -> maxLineLength 行缓冲大小,默认 64k +> maxLineLength 行缓冲大小,默认 8k,也就是一行最多只能容纳 8k 的字符内容。 + + +### cutMode + +> 截断模式,默认 false,需 maxLineLength 配合使用,直接看例子好了。 + +假设有个 file.txt 文件,有如下 5 行内容。 + +``` +// file.txt +111111 +22 +333333 +444 +555555 +``` + +``` js +var readLine = require('fs-readline'); + +var rl = readLine('./file.txt', {cutMode: true, maxLineLength: 4}); // 截断模式,一行最多容纳 4 个字符 +rl.on('line', function (line, idx) { + console.log(idx, line); +}); + +/** + * 输出为: + * 1 '1111' + * 2 '22' + * 3 '3333' + * 4 '444' + * 5 '5555' + */ +``` + +非常简单直观,行长度超过 4 的都被截断了,在某些特定的场景下还是比较适用的。 @@ -109,3 +162,6 @@ rl.on('line', function (line, idx) { [dependencies-url]: https://david-dm.org/52cik/fs-readline [dependencies-image]: https://img.shields.io/david/52cik/fs-readline.svg?style=flat + +[node-url]: https://nodejs.org +[node-image]: https://img.shields.io/node/v/gh-badges.svg diff --git a/index.js b/index.js index 6bea47f..26a97c6 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,6 @@ /** * @file fs-readline - * @author 52cik - * @email fe.52cik@gmail.com + * @author 52cik */ var util = require('util'); @@ -9,17 +8,29 @@ var ReadStream = require('fs').ReadStream; util.inherits(ReadLine, ReadStream); +var defaults = { // 默认配置 + maxLineLength: 8 * 1024, // 8k + cutMode: false, // 是否截断 + blankLine: true, // 是否保留空行 + retainBuffer: false // 是否转为字符串 +}; + function ReadLine(file, opts) { if (!(this instanceof ReadLine)) { return new ReadLine(file, opts); } var self = this; - opts = opts || {}; - opts.highWaterMark = opts.maxLineLength || opts.highWaterMark || 64 * 1024; // 64k + opts = Object.assign({}, defaults, opts || {}); + + if (!opts.cutMode) { // 非截断模式下读取长度和缓冲区长度一致 + opts.highWaterMark = opts.maxLineLength; + } + + var blankLine = opts.blankLine; // 是否忽略空格 + var retainBuffer = opts.retainBuffer; // 是否转为字符串 - var blankLine = opts.blankLine === undefined ? true : !!opts.blankLine; // 是否忽略空格 - var lineBuffer = new Buffer(opts.highWaterMark); // 行数据缓存 + var lineBuffer = new Buffer(opts.maxLineLength); // 行数据缓存 var lineSize = 0; // 行长度 var lineCount = 1; // 行号 @@ -44,7 +55,8 @@ function ReadLine(file, opts) { function emitLine(size, idx) { try { if (size > 0 || blankLine) { // 忽略空行 - self.emit('line', lineBuffer.slice(0, size), idx); + var line = lineBuffer.slice(0, size); + self.emit('line', retainBuffer ? line : line.toString(), idx); } } catch (e) { self.emit('error', e); diff --git a/package.json b/package.json index a0f24b0..4603d4f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fs-readline", - "version": "1.1.1", + "version": "2.0.0", "description": "按行读取文件,基于文件可读流。", "main": "./index.js", "scripts": { diff --git a/test/fixtures/cut-mode.txt b/test/fixtures/cut-mode.txt new file mode 100644 index 0000000..22f2e22 --- /dev/null +++ b/test/fixtures/cut-mode.txt @@ -0,0 +1,7 @@ +111111 +22 +333333 +444 +555555 +6666 +777777 diff --git a/test/index.js b/test/index.js index 8578f8b..9ba38a1 100644 --- a/test/index.js +++ b/test/index.js @@ -12,7 +12,7 @@ describe('测试用例:', function () { line .should.not.equal(null) .and.not.equal(undefined) - .and.be.a.Object(); + .and.be.a.String(); }); rl.on('end', function () { @@ -96,7 +96,7 @@ describe('测试用例:', function () { 14: 'дерево' }; - var rl = readLine('test/fixtures/file-in-win1251.txt'); + var rl = readLine('test/fixtures/file-in-win1251.txt', {retainBuffer: true}); rl.on('line', function (data, idx) { var line = iconv.decode(data, 'win1251'); @@ -108,4 +108,16 @@ describe('测试用例:', function () { }); }); + it('截断模式测试', function (done) { + var rl = readLine('test/fixtures/cut-mode.txt', {cutMode: true, maxLineLength: 4}); + + rl.on('line', function (line) { + line.should.match(/\d{0,4}/); + }); + + rl.on('end', function () { + done(); + }); + }); + }); \ No newline at end of file