从一个大文件到另一个大文件逐行复制?

时间:2013-03-03 06:28:16

标签: javascript node.js

我想用Node.js逐行处理一个大文件。它的大小为100MB,有500,000行。我找到了这个解决方案来读取输入文件中的行

javascript - node.js: read a text file into an array. (Each line an item in the array.) - Stack Overflow

现在是将每一行写入新的输出文件,所以我尝试

function readLines(input, func)
{
    var remaining = "";

    input.on("data", function(data)
    {
        remaining += data;
        var index = remaining.indexOf("\n");
        var last = 0;
        while (index > -1)
        {
            var line = remaining.substring(last, index);
            last = index + 1;
            func(line);
            index = remaining.indexOf("\n", last);
        }

        remaining = remaining.substring(last);
    });

    input.on("end", function()
    {
        if (remaining.length > 0)
        {
            func(remaining);
        }
    });
}

function write(data)
{
    var written = output.write(data);
}

var fs = require("fs");
var input = fs.createReadStream("input.txt");
var output = fs.createWriteStream("output.txt", {flags: "w"});
readLines(input, write);

然而,脚本非常慢,完全处理输入文件需要1个多小时,并且需要花费大量的CPU和RAM(CPU的数量为25,内存使用量高达200MB)。那么有人可以告诉我是否有任何方法来优化它?

1 个答案:

答案 0 :(得分:1)

你面临的问题是你经常1)追加一个字符串和2)切片。这两个操作都可能导致分配新字符串并将旧数据复制到一起,这很慢。旧字符串不再被引用,因此最终被垃圾收集释放,但这需要时间,因此占用大量内存。

当然有更简单的方法可以做到这一点,但我想你想要学习如何使用Node.JS中的流来完成它。在这种情况下,可以用来替换大量追加和切片的一般技术是将数据累积在字符串数组中。您可以稍后使用mystring.join("")将一个字符串数组合并到一个数组中,这会将["hello, ", "world"]转换为"hello, world"。创建一个字符串数组要快得多,然后将它们全部连接成一个大字符串,而不是创建字符串,我将每个字符串附加到最后一个字符串。

希望有帮助并且足以让您解决这个问题,并且仍然可以从中学到一些东西!