节点 - 从大文件中删除子字符串

我需要从文件中删除子字符串(仅出现在文件的特定已知行中)。

有一些简单的解决方案是将所有文件数据读取到字符串,删除子字符串,然后将固定数据写入文件。

这是我在这里找到的代码:

节点 js - 从文本文件中删除字符串

var data = fs.readFileSync('banlist.txt', 'utf-8');

var newValue = data.replace(new RegEx("STRING_TO_REMOVE"), '');

fs.writeFileSync('banlist.txt', newValue, 'utf-8');

我的问题是,文件很大 - 多达十亿行日志,所以我无法将所有内容读取到内存中。


HUH函数
浏览 85回答 4
4回答

慕田峪7331174

为什么不是一个简单的转换流和? 可以将回调作为第二个参数,即 如果您需要替换单词而不是完全删除它们。replace()replace.replace(/bad1|bad2|bad3/g, filterWords)const fs = require("fs")const { pipeline, Transform } = require("stream")const { join } = require("path")const readFile = fs.createReadStream("./words.txt")const writeFile = fs.createWriteStream(  join(__dirname, "words-filtered.txt"),  "utf8")const transformFile = new Transform({  transform(chunk, enc, next) {    let c = chunk.toString().replace(/bad/g, "replaced")    this.push(c)    next()  },})pipeline(readFile, transformFile, writeFile, (err) => {  if (err) {    console.log(err.message)  }})

慕工程0101907

https://nodejs.org/api/fs.html#fs_fs_read_fd_buffer_offset_length_position_callback不要一次读取整个文件...阅读其中的一小段缓冲。并用缓冲的片段寻找您的输入....然后增加您的缓冲区起始位置并再次执行此操作....建议让每个缓冲区开始,而不是在前一个缓冲区的末尾...但至少与所搜索数据的预期大小重叠,这样您就不会遇到一半数据位于一个缓冲区的末尾,而另一半位于另一个缓冲区的开头

千万里不及你

您可以使用文件读取流。但是,您必须找到一种方法来检测读取数据是否仅包含部分结果。

慕运维8079593

您可能想要做的是使用流,以便在部分读取后写入。此示例可能适合您。您需要将输出文本文件“.tmp”复制到原始文件上,以便在问题中获得相同的行为。它的工作原理是阅读一个块,然后查看你是否遇到了一条新线。然后它处理该行,写入它,然后将其从缓冲区中删除。这应该有助于解决您的记忆问题。var fs = require("fs");var readStream = fs.createReadStream("./BFFile.txt", { encoding: "utf-8" });var writeStream = fs.createWriteStream("./BFFile.txt.tmp");const STRING_TO_REMOVE = "badword";var buffer = ""readStream.on("data", (chunk) => {    buffer += chunk;    var indexOfNewLine = buffer.search("\n");    while (indexOfNewLine !== -1) {        var line = buffer.substring(0, indexOfNewLine + 1);        buffer = buffer.substring(indexOfNewLine + 1, buffer.length);        line = line.replace(new RegExp(STRING_TO_REMOVE), "");        writeStream.write(line);        indexOfNewLine = buffer.search("\n");    }})readStream.on("end", () => {    buffer = buffer.replace(new RegExp(STRING_TO_REMOVE), "");    writeStream.write(buffer);    writeStream.close();})此解决方案有一些假设,例如数据是UTF-8,每行可能只有1个坏词,每行都有一些文本(我没有测试),并且每行都以新行结尾而不是其他行结尾。以下是 Node 中流的文档,我的另一个想法是使用管道和转换流,但这似乎是过度杀戮。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript