在 Node JS 中只读取文件第一行的最有效方法是什么?
What is the most efficient way to read only the first line of a file in Node JS?
假设您有很多长文本文件,您只需要从每个文件的第一行提取数据(无需阅读任何进一步的内容)。在 Node JS 中最好的方法是什么?
谢谢!
//给你;
var lineReader = require('line-reader');
var async = require('async');
exports.readManyFiles = function(files) {
async.map(files,
function(file, callback))
lineReader.open(file, function(reader) {
if (reader.hasNextLine()) {
reader.nextLine(function(line) {
callback(null,line);
});
}
});
},
function(err, allLines) {
//do whatever you want to with the lines
})
}
我最终采用了这个解决方案,这似乎是迄今为止我见过的性能最高的解决方案:
var fs = require('fs');
var Q = require('q');
function readFirstLine (path) {
return Q.promise(function (resolve, reject) {
var rs = fs.createReadStream(path, {encoding: 'utf8'});
var acc = '';
var pos = 0;
var index;
rs
.on('data', function (chunk) {
index = chunk.indexOf('\n');
acc += chunk;
index !== -1 ? rs.close() : pos += chunk.length;
})
.on('close', function () {
resolve(acc.slice(0, pos + index));
})
.on('error', function (err) {
reject(err);
})
});
}
为了方便,我创建了一个 npm 模块,命名为“firstline”。
感谢@dandavis 建议使用 String.prototype.slice()
!
请试试这个:
https://github.com/yinrong/node-line-stream-util#get-head-lines
一旦得到头条线,它就会取消上游。
对于这种情况几乎有一个内置模块 - readline
。它避免弄乱块等。代码如下所示:
const fs = require('fs');
const readline = require('readline');
async function getFirstLine(pathToFile) {
const readable = fs.createReadStream(pathToFile);
const reader = readline.createInterface({ input: readable });
const line = await new Promise((resolve) => {
reader.on('line', (line) => {
reader.close();
resolve(line);
});
});
readable.close();
return line;
}
我知道这并不能完全回答问题,但对于那些正在寻找 READABLE 和 simple 方法的人来说:
const fs = require('fs').promises;
async function getFirstLine(filePath) {
const fileContent = await fs.readFile(filePath, 'utf-8');
return (fileContent.match(/(^.*)/) || [])[1] || '';
}
注意:
- 当然,这只适用于文本文件,根据您的描述我假设您使用的是文本文件
- 这个将处理空文件并且return一个空字符串
- 这个正则表达式非常高效,因为它很简单(没有
OR
条件`或复杂的匹配)并且只读取第一行
Node.js >= 16
在 Node.js 的所有当前版本中,readline.createInterface
可以用作异步迭代器,逐行读取文件 - 或者仅读取第一行。这也可以安全地用于空文件。
不幸的是,错误处理逻辑在 16 之前的 Node.js 版本中被破坏,其中某些文件系统错误可能不会被捕获,即使代码被包装在 try-catch 块中,因为方式异步错误在流中传播。所以我建议只在 Node.js >= 16.
中使用此方法
import { createReadStream } from "fs";
import { createInterface } from "readline";
async function readFirstLine(path) {
const inputStream = createReadStream(path);
try {
for await (const line of createInterface(inputStream)) return line;
return ''; // If the file is empty.
}
finally {
inputStream.destroy(); // Destroy file stream.
}
}
const firstLine = await readFirstLine("path/to/file");
假设您有很多长文本文件,您只需要从每个文件的第一行提取数据(无需阅读任何进一步的内容)。在 Node JS 中最好的方法是什么?
谢谢!
//给你;
var lineReader = require('line-reader');
var async = require('async');
exports.readManyFiles = function(files) {
async.map(files,
function(file, callback))
lineReader.open(file, function(reader) {
if (reader.hasNextLine()) {
reader.nextLine(function(line) {
callback(null,line);
});
}
});
},
function(err, allLines) {
//do whatever you want to with the lines
})
}
我最终采用了这个解决方案,这似乎是迄今为止我见过的性能最高的解决方案:
var fs = require('fs');
var Q = require('q');
function readFirstLine (path) {
return Q.promise(function (resolve, reject) {
var rs = fs.createReadStream(path, {encoding: 'utf8'});
var acc = '';
var pos = 0;
var index;
rs
.on('data', function (chunk) {
index = chunk.indexOf('\n');
acc += chunk;
index !== -1 ? rs.close() : pos += chunk.length;
})
.on('close', function () {
resolve(acc.slice(0, pos + index));
})
.on('error', function (err) {
reject(err);
})
});
}
为了方便,我创建了一个 npm 模块,命名为“firstline”。
感谢@dandavis 建议使用 String.prototype.slice()
!
请试试这个:
https://github.com/yinrong/node-line-stream-util#get-head-lines
一旦得到头条线,它就会取消上游。
对于这种情况几乎有一个内置模块 - readline
。它避免弄乱块等。代码如下所示:
const fs = require('fs');
const readline = require('readline');
async function getFirstLine(pathToFile) {
const readable = fs.createReadStream(pathToFile);
const reader = readline.createInterface({ input: readable });
const line = await new Promise((resolve) => {
reader.on('line', (line) => {
reader.close();
resolve(line);
});
});
readable.close();
return line;
}
我知道这并不能完全回答问题,但对于那些正在寻找 READABLE 和 simple 方法的人来说:
const fs = require('fs').promises;
async function getFirstLine(filePath) {
const fileContent = await fs.readFile(filePath, 'utf-8');
return (fileContent.match(/(^.*)/) || [])[1] || '';
}
注意:
- 当然,这只适用于文本文件,根据您的描述我假设您使用的是文本文件
- 这个将处理空文件并且return一个空字符串
- 这个正则表达式非常高效,因为它很简单(没有
OR
条件`或复杂的匹配)并且只读取第一行
Node.js >= 16
在 Node.js 的所有当前版本中,readline.createInterface
可以用作异步迭代器,逐行读取文件 - 或者仅读取第一行。这也可以安全地用于空文件。
不幸的是,错误处理逻辑在 16 之前的 Node.js 版本中被破坏,其中某些文件系统错误可能不会被捕获,即使代码被包装在 try-catch 块中,因为方式异步错误在流中传播。所以我建议只在 Node.js >= 16.
中使用此方法import { createReadStream } from "fs";
import { createInterface } from "readline";
async function readFirstLine(path) {
const inputStream = createReadStream(path);
try {
for await (const line of createInterface(inputStream)) return line;
return ''; // If the file is empty.
}
finally {
inputStream.destroy(); // Destroy file stream.
}
}
const firstLine = await readFirstLine("path/to/file");