fs.createWriteStream是否不立即创建文件? [英] fs.createWriteStream does not immediately create file?
问题描述
我从http 函数进行了简单的下载,如下所示(为简化起见,省略了错误处理):
I have made a simple download from http function as below (error handling is omitted for simplifcation):
function download(url, tempFilepath, filepath, callback) {
var tempFile = fs.createWriteStream(tempFilepath);
http.request(url, function(res) {
res.on('data', function(chunk) {
tempFile.write(chunk);
}).on('end', function() {
tempFile.end();
fs.renameSync(tempFile.path, filepath);
return callback(filepath);
})
});
}
但是,由于我异步调用download()
数十次,它很少报告fs.renameSync
错误,并抱怨在tempFile.path
找不到文件.
However, as I call download()
tens of times asynchronously, it seldom reports error on fs.renameSync
complaining it cannot find file at tempFile.path
.
Error: ENOENT, no such file or directory 'xxx'
我使用了相同的URL列表来对其进行测试,但它大约30%的时间都失败了.一次下载一个相同的URL列表.
I used the same list of urls to test it, and it failed about 30% of time. The same list of urls worked when downloaded one by one.
经过更多测试,我发现下面的代码
Testing some more, I found out that the following code
fs.createWriteStream('anypath');
console.log(fs.exist('anypath'));
console.log(fs.exist('anypath'));
console.log(fs.exist('anypath'));
并不总是打印true
,但有时第一个答案打印false
.
does not always print true
, but sometimes the first answer prints false
.
我怀疑太多的异步fs.createWriteStream
调用不能保证文件的创建.这是真的?有什么方法可以保证文件的创建吗?
I am suspecting that too many asynchronous fs.createWriteStream
calls cannot guarantee the file creation. Is this true? Are there any methods to guarantee file creation?
推荐答案
在您从流中收到'open'
事件之前,您不应该在tempFile
写入流上调用write
.在看到该事件之前,该文件将不存在.
You shouldn't call write
on your tempFile
write stream until you've received the 'open'
event from the stream. The file won't exist until you see that event.
对于您的功能:
function download(url, tempFilepath, filepath, callback) {
var tempFile = fs.createWriteStream(tempFilepath);
tempFile.on('open', function(fd) {
http.request(url, function(res) {
res.on('data', function(chunk) {
tempFile.write(chunk);
}).on('end', function() {
tempFile.end();
fs.renameSync(tempFile.path, filepath);
return callback(filepath);
});
});
});
}
供您测试:
var ws = fs.createWriteStream('anypath');
ws.on('open', function(fd) {
console.log(fs.existsSync('anypath'));
console.log(fs.existsSync('anypath'));
console.log(fs.existsSync('anypath'));
});
这篇关于fs.createWriteStream是否不立即创建文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!