Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory Node.js在逐位读取大量文件时内存不足_Memory_Node.js_Stream_Buffer - Fatal编程技术网

Memory Node.js在逐位读取大量文件时内存不足

Memory Node.js在逐位读取大量文件时内存不足,memory,node.js,stream,buffer,Memory,Node.js,Stream,Buffer,我正在尝试编写一点JS,它将读取一个文件并将其写入流。这个文件非常大,所以我必须一点一点地读。看来我不应该记忆犹新,但我确实记忆犹新。代码如下: var size=fs.statSync(“tmpfile.tmp”).size; var fp=fs.openSync(“tmpfile.tmp”,“r”); 用于(变量pos=0;pos2GB的内存。最终我发现输出流可能比输入流慢,并且外流缓冲了大量内存数据。我可以通过每100次写入外流暂停一次内流,然后等待外流清空来解决这个问题。这给了外流跟上内

我正在尝试编写一点JS,它将读取一个文件并将其写入流。这个文件非常大,所以我必须一点一点地读。看来我不应该记忆犹新,但我确实记忆犹新。代码如下:

var size=fs.statSync(“tmpfile.tmp”).size;
var fp=fs.openSync(“tmpfile.tmp”,“r”);
用于(变量pos=0;pos
由于某些原因,它会命中26490000,然后抛出
致命错误:调用\u和\u重试\u 2分配失败-进程内存不足
。我认为
data\u output.write()
调用会强制它将数据写入
data\u output
,然后从内存中丢弃,但我可能错了。某种原因导致数据留在内存中,我不知道它会是什么。非常感谢您的帮助。

根据,
数据输出。如果字符串已刷新,write(…)
将返回
true
,如果未刷新(由于内核缓冲区已满),则返回
false
。这是什么样的小溪


另外,我(相当)肯定这不是问题所在,但是:为什么在每次循环迭代中分配一个新的
缓冲区
?在循环之前初始化
buf
不是更有意义吗?

您应该使用管道,例如:

var fp = fs.createReadStream("tmpfile.tmp");
fp.pipe(data_output);
有关更多信息,请查看:


编辑:顺便说一句,您的实现中的问题是,通过这样分块执行,写入缓冲区不会被刷新,而且在将大部分文件写回之前,您将读取整个文件。

我不知道同步文件函数是如何实现的,但您是否考虑过使用异步文件?这更有可能允许垃圾收集和i/o刷新发生。因此,您将在前一次读取的回调函数中触发下一次读取,而不是for循环

大致如下(请注意,根据其他注释,我正在重用缓冲区):

var buf=新缓冲区(50000),
var pos=0,字节读取;
函数readNextChunk(){
财政司司长读(fp、buf、0、50000、pos、,
函数(err,bytesRead){
如果(错误){
//处理错误
}
否则{
数据输出写入(buf.toString(“utf8”,0,字节读取));
pos+=字节读取;

如果(pos我遇到了一个非常类似的问题。我正在读取一个包含10万行的非常大的csv文件,并写出它的json等价物。我在windows任务管理器中看到我的进程使用了>2GB的内存。最终我发现输出流可能比输入流慢,并且外流缓冲了大量内存数据。我可以通过每100次写入外流暂停一次内流,然后等待外流清空来解决这个问题。这给了外流跟上内流的时间。我认为这对讨论来说并不重要,但我使用“readline”一次处理一行csv文件

我还发现,如果不是将每一行写入扩展流,而是将大约100行连接在一起,然后将它们写入一起,这也会改善内存状况,有利于更快的操作

最后,我发现我只需要70M内存就可以完成文件传输(csv->json)

下面是我的write函数的代码片段:

var write_counter = 0;
var out_string = "";
function myWrite(inStream, outStream, string, finalWrite) {
    out_string += string;
    write_counter++;
    if ((write_counter === 100) || (finalWrite)) {
        // pause the instream until the outstream clears
        inStream.pause();
        outStream.write(out_string, function () {
            inStream.resume();
        });
        write_counter = 0;
        out_string = "";
    }
}

delete buf;
无效,请尝试
buf=null
啊,很好的调用。那是我刚刚调试的,试图弄清楚在每次迭代后删除它是否会有任何作用。这实际上是将一个大文件发送到远程存储,这是HTTP。Re:HTTP:这很有意义。读取文件的速度比发送文件的速度快得多网络和
write
在字节实际发送之前不会阻塞。(如果字节尚未发送,它只会返回
false
,然后在发送后发出
drain
事件。)
var write_counter = 0;
var out_string = "";
function myWrite(inStream, outStream, string, finalWrite) {
    out_string += string;
    write_counter++;
    if ((write_counter === 100) || (finalWrite)) {
        // pause the instream until the outstream clears
        inStream.pause();
        outStream.write(out_string, function () {
            inStream.resume();
        });
        write_counter = 0;
        out_string = "";
    }
}