gpt4 book ai didi

javascript - 使用可写流写入文件时出现 Node.js EBADF 错误

转载 作者:行者123 更新时间:2023-11-30 18:21:33 27 4
gpt4 key购买 nike

我尝试使用 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.createReadStreamfs.createWriteStream,但只设法将第一行写入 output.txt,因为脚本以错误结尾:

{ [错误:EBADF,写入] errno:9,代码:'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

特别是任何排队的写入数据都不会被发送,这就是您丢失某些输出的原因。

基本上,如果您希望 ReadStream 提前关闭,您应该只在 ReadStream 上调用 destroy,就像在 n > 100 的情况下一样。然后您想改用 WriteStream 的 end,以便流有时间写入所有缓冲数据。

这是一个简化版本,我认为它应该可以正常工作。我也不会费心绑定(bind) 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();
});

关于javascript - 使用可写流写入文件时出现 Node.js EBADF 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11945405/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com