Javascript Nodejs-从大型文件中删除子字符串

Javascript Nodejs-从大型文件中删除子字符串,javascript,node.js,Javascript,Node.js,我需要从文件中删除仅出现在文件特定已知行中的子字符串 有一些简单的解决方案,可以将所有文件数据读入字符串,删除子字符串,然后将固定数据写入文件 下面是我在这里找到的代码: 我的问题是,这个文件很大——多达十亿行日志,所以我无法将所有内容读取到内存中 不要一次读完整个文件。。。读一小段缓冲区。。然后用缓冲块查找您的输入。。。。然后增加缓冲区的起始位置,然后再次执行。。。。建议每个缓冲区不要在前一个缓冲区的末尾启动。。。但重叠至少是所查找数据的预期大小,这样您就不会遇到一半的数据位于一个缓冲区的末尾

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

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

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

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


不要一次读完整个文件。。。读一小段缓冲区。。然后用缓冲块查找您的输入。。。。然后增加缓冲区的起始位置,然后再次执行。。。。建议每个缓冲区不要在前一个缓冲区的末尾启动。。。但重叠至少是所查找数据的预期大小,这样您就不会遇到一半的数据位于一个缓冲区的末尾,另一半位于另一个缓冲区的开头。您可以使用。但是,您必须找到一种方法来检测读取的数据是否只包含部分结果。

您可能要做的是使用流,以便在部分读取之后进行写入。这个例子可能对你有用。您需要将输出文本文件.tmp复制到原始文本文件上,以获得与问题相同的行为。它的工作原理是阅读一段文字,然后看看你是否遇到了一条新线。然后它处理该行,写入该行,然后将其从缓冲区中删除。这将有助于解决你的记忆问题

var fs=所需参数; var readStream=fs.createReadStream./BFFile.txt,{encoding:utf-8}; var writeStream=fs.createWriteStream./BFFile.txt.tmp; const STRING_TO_REMOVE=坏字; 变量缓冲区= readStream.ondata,chunk=>{ 缓冲区+=块; var indexOfNewLine=buffer.search\n; 而indexOfNewLine!=-1{ var line=buffer.substring0,indexOfNewLine+1; buffer=buffer.substringindexOfNewLine+1,buffer.length; line=line.replacenew RegExpSTRING_TO_REMOVE; writeStream.writeline; indexOfNewLine=缓冲区。搜索\n; } } readStream.onend,=>{ buffer=buffer.replacenew RegExpSTRING_TO_REMOVE; writeStream.writebuffer; writeStream.close; } 这个解决方案有一些假设,比如数据是UTF-8,每行可能只有一个坏字,每行都有一些我没有测试过的文本,每行都以新行结束,而不是其他行结束

这是你的文件
我的另一个想法是使用管道和转换流,但这似乎有些过分。

您可以使用此代码来完成。我正在使用fs流。它是为在小内存中逐块读取大文件而创建的


为什么不是一个简单的转换流和替换?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)
  }
})

在这里检查如何创建逐行读取流,然后您只需创建到另一个文件的写入流,并将您的读取流通过管道传输到写入流中。。。如果数据那么大,我建议将其移动到数据库,而不是平面文件
const fs = require('fs');

const readStream = fs.createReadStream('./XXXXX');
const writeStream = fs.createWriteStream('./XXXXXXX');

readStream.on('data', (chunk) => {
  const data = chunk.toString().replace('STRING_TO_REMOVE', 'XXXXXX');
  writeStream.write(data);
});

readStream.on('end', () => {
  writeStream.close();
});

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)
  }
})