You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中fs.read()复制文件时目标文件末尾出现异常字符的原因

Node.js 用 fs.read() 复制文件末尾出奇怪字符的原因

两种方法的差异核心在于是否正确处理了每次读取的有效字节数:

  • 第一种默认参数的写法问题:
    当你不传Buffer调用fs.read()时,Node.js会自动创建一个固定大小的默认Buffer(一般是16KB)。每次读取时,就算源文件剩下的内容不够填满这个Buffer,Buffer里没被新内容覆盖的区域会残留之前的旧数据或者初始化垃圾值。如果你的代码直接把整个Buffer写入目标文件,而不是只写入fs.read()回调返回的bytesRead对应的有效内容,这些残留数据就会变成des.txt末尾的奇怪字符。

  • 第二种手动分配Buffer的写法为什么正常:
    手动分配Buffer时,你大概率会在读取和写入时严格对应bytesRead值——要么根据文件剩余大小调整Buffer长度,要么写入时只截取Buffer中前bytesRead个字节的有效内容。这样最后一次写入的只有源文件的剩余内容,不会带上Buffer里的无效垃圾数据,自然就不会出现异常字符。

举个直观的代码对比:

错误的默认参数写法(会产生奇怪字符)

const fs = require('fs');
const srcFd = fs.openSync('src.txt', 'r');
const desFd = fs.openSync('des.txt', 'w');

function copy() {
  fs.read(srcFd, (err, bytesRead, buf) => {
    if (err) throw err;
    if (bytesRead === 0) {
      fs.closeSync(srcFd);
      fs.closeSync(desFd);
      return;
    }
    // 错误:直接写入整个Buffer,包含无效残留数据
    fs.write(desFd, buf, (err) => {
      if (err) throw err;
      copy();
    });
  });
}

copy();

正确的写法(不管是否手动分配Buffer,关键是处理bytesRead)

const fs = require('fs');
const srcFd = fs.openSync('src.txt', 'r');
const desFd = fs.openSync('des.txt', 'w');
// 手动分配Buffer,也可以用默认Buffer,核心是写入时取有效长度
const buf = Buffer.alloc(16384);

function copy() {
  fs.read(srcFd, buf, 0, buf.length, null, (err, bytesRead) => {
    if (err) throw err;
    if (bytesRead === 0) {
      fs.closeSync(srcFd);
      fs.closeSync(desFd);
      return;
    }
    // 正确:只写入实际读到的bytesRead长度的内容
    fs.write(desFd, buf, 0, bytesRead, (err) => {
      if (err) throw err;
      copy();
    });
  });
}

copy();

内容的提问来源于stack exchange,提问作者Baba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 08:59:16