如何从JS中的ArrayBuffer写入文件

我正在为Meteor框架写一个file upload器。 其原理是以4096比特的小数据包将客户端上的文件从ArrayBuffer中分离出来,这些数据包通过Meteor.method发送到服务器。

下面的简化代码是发送一个块到服务器的客户端的一部分,重复直到偏移量达到data.byteLength

// data is an ArrayBuffer var total = data.byteLength; var offset = 0; var upload = function() { var length = 4096; // chunk size // adjust the last chunk size if (offset + length > total) { length = total - offset; } // I am using Uint8Array to create the chunk // because it can be passed to the Meteor.method natively var chunk = new Uint8Array(data, offset, length); if (offset < total) { // Send the chunk to the server and tell it what file to append to Meteor.call('uploadFileData', fileId, chunk, function (err, length) { if (!err) { offset += length; upload(); } } } }; upload(); // start uploading 

下面的简化代码是接收块并将其写入文件系统的服务器上的部分:

 var fs = Npm.require('fs'); var Future = Npm.require('fibers/future'); Meteor.methods({ uploadFileData: function(fileId, chunk) { var fut = new Future(); var path = '/uploads/' + fileId; // I tried that with no success chunk = String.fromCharCode.apply(null, chunk); // how to write the chunk that is an Uint8Array to the disk ? fs.appendFile(path, chunk, 'binary', function (err) { if (err) { fut.throw(err); } else { fut.return(chunk.length); } }); return fut.wait(); } }); 

我没有写一个有效的文件到磁盘,实际上文件被保存,但我不能打开它,当我在文本编辑器中看到的内容,它是类似于原始文件(例如一个JPG),但有些字符是不同的,我认为这可能是一个编码问题,因为文件大小是不一样的,但我不知道如何解决这个问题…

保存文件就像使用Uint8Array对象创build一个新的Buffer一样简单:

 // chunk is the Uint8Array object fs.appendFile(path, new Buffer(chunk), function (err) { if (err) { fut.throw(err); } else { fut.return(chunk.length); } }); 

只是想补充一点,在新的meteor,你可以避免一些callback地狱async/await 。 等待也会抛出并推到客户端的错误

 Meteor.methods({ uploadFileData: async function(file_id, chunk) { var path = 'somepath/' + file_id; // be careful with this, make sure to sanitize file_id await fs.appendFile(path, new Buffer(chunk)); return chunk.length; } }); 

build立在Karl.S的答案 ,这对我来说,在任何框架之外:

 fs.appendFileSync(outfile, new Buffer(arrayBuffer));