使用 Node.js 读取文本文件?

IT技术 javascript node.js
2021-02-10 06:44:11

我需要在终端中传入一个文本文件,然后从中读取数据,我该怎么做?

node server.js file.txt

如何从终端传入路径,如何在另一侧阅读?

6个回答

您将需要使用该process.argv数组来访问命令行参数以获取文件名和FileSystem module (fs)以读取文件。例如:

// Make sure we got a filename on the command line.
if (process.argv.length < 3) {
  console.log('Usage: node ' + process.argv[1] + ' FILENAME');
  process.exit(1);
}
// Read the file and print its contents.
var fs = require('fs')
  , filename = process.argv[2];
fs.readFile(filename, 'utf8', function(err, data) {
  if (err) throw err;
  console.log('OK: ' + filename);
  console.log(data)
});

稍微分解一下,process.argv通常长度为 2,第 0 个项目是“节点”解释器,第一个项目是节点当前正在运行的脚本,之后的项目在命令行上传递。从 argv 中提取文件名后,您就可以使用文件系统函数来读取文件并对其内容执行任何您想要的操作。示例用法如下所示:

$ node ./cat.js file.txt
OK: file.txt
This is file.txt!

[编辑]正如@wtfcoder 所提到的,使用“ fs.readFile()”方法可能不是最好的主意,因为它会在将文件交给回调函数之前缓冲文件的全部内容。这种缓冲可能会使用大量内存,但更重要的是,它没有利用 node.js 的核心特性之一——异步、事件 I/O。

处理大文件(或任何文件,实际上)的“节点”方式是使用fs.read()和处理每个可用块,因为它可以从操作系统中获得。但是,这样读取文件需要您自己(可能)对文件进行增量解析/处理,并且某些缓冲量可能是不可避免的。

如果文本文件很大,这不是一个好主意,因为它会被全部读入内存,如果你处理一个 1000mb 的 CSV 文件,看看 fs.createFilestream,你需要注意行拆分,但作为数据块不会(在大多数情况下)落在线边界上(有些人已经提出了解决方案 - 谷歌)
2021-03-21 06:44:11
我发布了一个类似问题的解决方案,用于解析一个非常大的文件,使用流,同步。参见:stackoverflow.com/questions/16010915/...
2021-03-29 06:44:11
@wtfcoder:是的,非常好。我的目的只是为了演示读取在命令行上命名的文件的简单情况;显然有许多微妙之处(尤其是性能)超出了这个问题的范围。
2021-04-03 06:44:11
@fancy:尝试var lines = data.split(/\r?\n/);,然后数组“行”将包含每一行。
2021-04-05 06:44:11
太棒了,非常感谢,非常有帮助。我怎么能按行拆分这些数据?
2021-04-12 06:44:11

使用节点对 fs 进行签名。

var fs = require('fs');

try {  
    var data = fs.readFileSync('file.txt', 'utf8');
    console.log(data.toString());    
} catch(e) {
    console.log('Error:', e.stack);
}
@RichWerden 在这种情况下,“同步”是什么意思?
2021-03-30 06:44:11
在 Node 中,当某些事情是“同步的”时,它会停止/阻止系统做任何其他事情。假设您有一个节点网络服务器 - 如果在上述情况发生时有任何其他请求进入,服务器将不会/无法响应,因为它正忙于读取文件。
2021-04-03 06:44:11
请注意,这是同步版本。
2021-04-08 06:44:11

恕我直言,fs.readFile()应该避免,因为它将所有文件加载到内存中,并且在读取所有文件之前它不会调用回调。

阅读文本文件最简单的方法是逐行阅读。我推荐一个BufferedReader

new BufferedReader ("file", { encoding: "utf8" })
    .on ("error", function (error){
        console.log ("error: " + error);
    })
    .on ("line", function (line){
        console.log ("line: " + line);
    })
    .on ("end", function (){
        console.log ("EOF");
    })
    .read ();

对于像 .properties 或 json 文件这样的复杂数据结构,您需要使用解析器(在内部它也应该使用缓冲读取器)。

我看到 BufferedReader 现在已被弃用。
2021-03-19 06:44:11
BufferedReader 可能已更改其签名。我不得不用 BufferedReader,DataReader 替换 BufferedReader,其中 BufferedReader 是module。参见github.com/Gagle/Node-BufferedReader
2021-03-23 06:44:11
感谢您指出这项技术。您说得对,这可能是最好的方法,但我只是认为在这个问题的上下文中有点令人困惑,我认为这是在询问一个要求不高的用例。如上所述,如果只是将一个小文件传递给命令行工具,则没有理由不使用fs.readFile()fs.readFileSync()它必须是一个巨大的文件才能引起明显的等待。喜欢的package.json一个JSON配置文件很可能是在1 KB,所以你可以fs.readFile()JSON.parse()它。
2021-03-31 06:44:11

您可以使用 readstream 和 pipe 逐行读取文件,而无需一次将所有文件读入内存。

var fs = require('fs'),
    es = require('event-stream'),
    os = require('os');

var s = fs.createReadStream(path)
    .pipe(es.split())
    .pipe(es.mapSync(function(line) {
        //pause the readstream
        s.pause();
        console.log("line:", line);
        s.resume();
    })
    .on('error', function(err) {
        console.log('Error:', err);
    })
    .on('end', function() {
        console.log('Finish reading.');
    })
);

我发布了一个完整的例子,我终于开始工作了。在这里,我正在rooms/rooms.txt从脚本中读取文件rooms/rooms.js

var fs = require('fs');
var path = require('path');
var readStream = fs.createReadStream(path.join(__dirname, '../rooms') + '/rooms.txt', 'utf8');
let data = ''
readStream.on('data', function(chunk) {
    data += chunk;
}).on('end', function() {
    console.log(data);
});