Node.js可写入stream创build错误的文件(更大和不可读)
我正在写一段代码,通过Socket.io将文件从Angular.js客户端发送到Node.js服务器。 客户端将文件分块并通过Socket.io发送到服务器。
该文件在客户端使用JavaScript的FileReader
读取:
var chunkSize = 524288, // 0.5mb reader = new FileReader(); reader.onload = function(e) { // ok, this one is very simplified so that I don't have to copy // all of my code here, but basically I send files with an offset // like: // file.data.substr(offset, Math.min(chunkSize, file.size - offset)); // for testing purposes I use a file smaller than 0.5mb, so it // gets sent in one chunk var chunk = e.target.result.substr(0, chunkSize); // this one is also simplified, I use unique file ids to write to // a certain file // during testing I use a file of 48014 bytes, if I console.log() // it, it says that chunk.length is 48014 bytes socket.emit('fileUpload', { chunk: chunk }); }; reader.readAsBinaryString(file);
然后这个事件到达服务器:
// this one is also simplified, in fact I use three events, not one: // fileUploadStart, fileUpload and fileUploadEnd, but for the sake of // this question it's irrelevant socket.on('fileUpload', function(data) { var stream = fs.createWriteStream(data.id + '.tmp')); stream.on('drain', function() { socket.emit('streamDrained', { description: 'Stream drained.', size: stream.bytesWritten }); }); stream.write(data.chunk); });
然后在客户端上,我得到了streamDrained
事件,它告诉我,69127字节被写入而不是48014(这是原始文件的大小)。 如果我检查生成的文件,它也是69127字节,并已损坏。 原始文件是.pdf
,生成的文件可以用PDF阅读器打开,它与原始页面数量相同,但都是空白的。
另外,如果我的console.log()
是服务器接收到的chunk的长度,也是48014字节的长度,但是在写入数据stream之后,文件结果是69127字节。
似乎我在FileReader
的概念,或在Writable Stream
,或在Socket.io
,或任何它的组合的东西丢失的东西。 很感谢任何forms的帮助。
这里最可能发生的情况是,当二进制数据中发现无效的UTF-8字符序列时,将二进制数据转换为UTF-8string,这可能会导致额外的字节(无效的replace字符字节)。
要在socket.io 1.x中传输二进制数据,您需要确保该chunk
是Blob
, ArrayBuffer
或File
实例。 然后在节点端, data.chunk
应该是包含相同二进制数据的Buffer
。
一个示例解决scheme是使用reader.readAsArrayBuffer()
而不是reader.readAsBinaryString()
。 还应该注意的是, reader.readAsBinaryString()
已被弃用 。