节点.js 使用可写流写入文件时出现 EBADF 错误
Node.js EBADF error when writing file using writable stream
我尝试使用 Node.js 来处理一个 500MB 的 Apache 日志文件,将其语法从
ip.ip.ip.ip - - [02/Aug/2012:05:01:17 -0600] "GET /path/of/access/ HTTP/1.1" 302 26
自
ip.ip.ip.ip - - 02/Aug/2012:05:01:17 GET /path/of/access/ HTTP/1.1 302 26
,然后写入另一个文本文件。
为了更好的内存控制和性能,我使用了fs.createReadStream
和fs.createWriteStream
,但只设法将第一行写入output.txt
,因为脚本以错误结尾:
{ [Error: EBADF, write] errno: 9, code: 'EBADF' }
在这里,我发布了一些可能有助于调试的信息。
input.txt
主管 :
ip.ip.ip.ip - - [02/Aug/2012:05:01:17 -0600] "GET /path/of/access/ HTTP/1.1" 302 26
ip.ip.ip.ip - - [02/Aug/2012:05:01:17 -0600] "GET /path/of/access/ HTTP/1.1" 302 26
ip.ip.ip.ip - - [02/Aug/2012:05:01:17 -0600] "GET /path/of/access/ HTTP/1.1" 302 26
ip.ip.ip.ip - - [02/Aug/2012:05:01:17 -0600] "GET /path/of/access/ HTTP/1.1" 302 26
ip.ip.ip.ip - - [02/Aug/2012:05:01:17 -0600] "GET /path/of/access/ HTTP/1.1" 302 26
ip.ip.ip.ip - - [02/Aug/2012:05:01:17 -0600] "GET /path/of/access/ HTTP/1.1" 302 26
ip.ip.ip.ip - - [02/Aug/2012:05:01:18 -0600] "GET /path/of/access/ HTTP/1.1" 302 26
output.txt
内容 :
ip.ip.ip.ip - - [02/Aug/2012:05:01:17 -0600] "GET /path/of/access/ HTTP/1.1" 302 26
整个脚本:
var fs = require('fs');
var data ='';
var n=0; //For line control
var r = fs.createReadStream('./input.txt',{
encoding: 'ascii',
start:0,
// end: 100000,
});
var w = fs.createWriteStream('./output.txt',{
encoding:'ascii'
});
function put(line){ //write into w;
++n;
w.write(line+''n');
}
function end(){
r.destroy();
w.destroy();
}
function onData(chunk){
var hasNewline = chunk.indexOf(''n')!==-1;
if(hasNewline){
var arr = chunk.split(''n');
var first = arr.shift();
var last = arr.pop();
data+=first;
put(data); //write a complete line
arr.forEach(function(line){
put(line); //write a complete line
});
data=last;
}else{
data+=chunk;
}
if(n>100){
end();
}
}
function onErr(e){
console.log(e);
}
r.addListener( "data", onData);
r.addListener( "end", end);
r.addListener('error',onErr);
w.addListener('error',onErr);
我可以看到两个问题。
首先,您的end
函数在 ReadStream 上调用destroy
,但在一般情况下,这是从 end
事件触发的,这意味着流已经关闭,并且它将自动调用destroy
。这意味着r.destroy
将被调用两次,从而触发错误。这是您看到打印的错误的原因。
第二个问题是您在 WriteStream 上调用destroy
。我建议你去阅读文档:http://nodejs.org/api/stream.html#stream_stream_destroy_1
特别是Any queued write data will not be sent
,这就是为什么您缺少一些输出的原因。
基本上,只有在您希望 ReadStream 提前关闭时才应该在 ReadStream 上调用destroy
,就像在您的n > 100
情况下一样。然后,您希望改用 WriteStream 的end
,以便流有时间写入所有缓冲数据。
这是一个简化版本,我认为它应该同样工作。我也不会打扰绑定error
因为无论如何错误都会自动打印到控制台。
var fs = require('fs');
var data ='';
var n=0; //For line control
var r = fs.createReadStream('./input.txt',{
encoding: 'ascii',
start:0,
// end: 100000,
});
var w = fs.createWriteStream('./output.txt',{
encoding:'ascii'
});
r.addListener( "data", function(chunk){
data += chunk;
var lines = data.split(''n');
data = lines.pop();
lines.forEach(function(line){
if (!r.readable) return; // If already destroyed
if (n >= 100) {
// Stop any more 'data' events and close the file.
// This will also trigger 'close' below and close the writestream.
r.destroy();
return;
}
n++;
w.write(line + ''n');
});
});
r.addListener( "end", function(){
// When we hit the end of the file, close the write stream,
// and write any remaining line content
w.write(data);
});
r.addListener("close", function(){
w.end();
});
- Node.js v6.2.0类扩展不是函数错误
- Jquery菜单操作不稳定,定位不正确,存在一般错误
- document.open/document.write没有正确地清除chrome中的文档——这是chrome的错误吗
- 试图在引导模式内动态生成图表,得到offsetWidth错误
- 为什么会出现错误;未捕获的类型错误:undefined不是函数;
- 我如何修复包含在captcha的addthis中的错误
- 同样,同样的错误'ahorcado.js:26未捕获类型错误:无法读取属性'beginPath'
- 节点是否需要模块传递带有方括号的arg?这是个错误吗
- Webpack/Rect:遵循egghead.io教程,但出现错误:您可能需要一个合适的加载程序来处理此文件类型
- CKFinder 3为所选文件返回错误的URL
- 同位素库错误:未捕获错误无布局模式包装生产线8
- 铬:“;未捕获的语法错误:意外的标记:"
- 如何通过自己获得Chrome扩展的用户反馈/错误报告
- 相位器状态未捕获参考错误
- /undefined在我的404错误日志中多次出现
- Javascript未捕获语法错误意外的标识符错误
- javascript:如何在antlr生成的Lexer中进行错误处理
- Angularjs工厂注入错误
- 可以设置“;文件名"发生错误时显示的内联脚本标记的
- 节点.js 使用可写流写入文件时出现 EBADF 错误