1

我正在尝试使用节点文件流和自定义转换功能修改一些文件。这是变换函数:

const TransformStream = function() {
  Transform.call(this, {objectMode: true});
};
util.inherits(TransformStream, Transform);

TransformStream.prototype._transform = function(chunk, encoding, callback) {
  let line = chunk.toString()
  if (!this.findLinesMode && lineStartRe.test(line)) {
    this.findLinesMode = true
    this.lines = []
  }
  if (this.findLinesMode) {
    this.lines.push(line)
  }
  if (this.findLinesMode && lineEndRe.test(line)) {
    this.findLinesMode = false
    line = this.lines.join('').replace(re, (str, match) => match.trim())
  }
  if (!this.findLinesMode) {
    this.push(line + '\n')
  }

  callback()
};

我尝试在以下代码中使用它:

byline(fs.createReadStream(filePath, {encoding: 'utf8'}))
  .pipe(new TransformStream())
  .pipe(fs.createWriteStream(filePath))

但是,该文件最终为空。

我相信转换器代码可以按预期工作,因为我尝试将其通过管道传输到process.stdout并且输出正是我想要的。

我的问题是:我做错了什么,我可以尝试解决什么问题?

4

1 回答 1

2

这不是您的转换器代码的问题,而是您打开一个文件进行写入的问题,您可能在读取任何内容之前就覆盖了该文件。

在 shell 中也是一样的。如果你运行:

cat < file.txt > file.txt

或者:

tr a-z A-Z < x.txt > x.txt

这将导致文件为空。

您必须通过管道传输到一个临时文件,然后用新文件替换旧文件。或者将旧文件重命名为其他临时名称,以正确的名称打开新文件并将重命名的文件通过管道传输到旧文件,在途中进行转换。

确保使用安全的方式为临时文件命名。您可以使用以下模块:

于 2016-12-23T13:14:08.593 回答