我有一个Node.js脚本,它读取文件的内容,对其内容进行一些转换,并记录输出:
var transformer = require('./transformer'),
fs = require('fs'),
file = process.argv[2];
if (!file) {
throw 'no file specified\n';
}
fs.readFile(file, 'utf-8', function (err, data) {
if (err) {
throw err;
}
transformer.transform(data, function (text) {
console.log(text);
});
});
这很好用:
$ node transform.js myfile.txt
这有效:
$ node transform.js myfile.txt > anotherfile.txt
但是,当我尝试将输出重定向到我正在阅读的同一个文件时,该文件变为空白:
$ node transform.js myfile.txt > myfile.txt
使用tee
同样的事情:
$ node transform.js myfile.txt | tee myfile.txt
奇怪的是,这有效:
$ node transform.js myfile.txt >> myfile.txt
但我不想附加到该文件 - 我想覆盖其内容。
我认为问题是,因为fs.readFile
是异步的,所以console.log
也是异步调用的 - 也就是说,它获取数据块而不是一次性所有数据。我想我可以使用fs.readFileSync
代替,但是正确的方法是什么?
答案 0 :(得分:1)
问题是
我认为你想要的是:
有几种方法可以做到这一点:
1)同步读取文件。 Node.js 0.12 supports this
var transformer = require('./transformer'),
fs = require('fs'),
file = process.argv[2];
if (!file) {
throw 'no file specified\n';
}
fs.readFileSync(file, 'utf-8', function (err, data) {
if (err) {
throw err;
}
transformer.transform(data, function (text) {
console.log(text);
});
});
2)使用“溪流”
这是最好的方法。特别是如果你想学习Node.js
我了解流知识的最佳方式来自NodeSchool:http://nodeschool.io/#workshoppers尝试stream-adventure
。
最后,你拥有这类问题。
祝你好运!答案 1 :(得分:1)
问题实际上不在Node内,而是在shell中。使用>
重定向时,shell执行的第一件事是打开文件进行写入,清空文件。你的程序从那个空文件中读取,在你的情况下,空输入意味着空输出。
无论myfile.txt
的初始内容是什么,这都会导致文件为空:
$ cat myfile.txt > myfile.txt
一种解决方案是在Node脚本中编写文件而不是使用重定向。您已经在那里指定和读取文件,那么为什么不在argv
中指定输出文件并写入它而不是使用shell重定向?只需要注意构建代码,以便读取和写入同一个文件。
正如@slebetman在评论中指出的那样,另一种解决方案是cat myfile.txt > tmp; mv tmp myfile.txt
(或我的首选:cat myfile.txt > tmp && mv tmp myfile.txt
)。