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
相关产品推荐
相关产品推荐

