Javascript 如何从JS中的ArrayBuffer写入文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31581254/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to write a file from an ArrayBuffer in JS
提问by Karl.S
I am trying to write a file uploader for Meteor framework. The principle is to split the fileon the client from an ArrayBuffer in small packets of 4096 bits that are sent to the server through a Meteor.method.
我正在尝试为 Meteor 框架编写一个文件上传器。原理是将客户端上的文件从 ArrayBuffer 拆分成 4096 位的小数据包,通过 Meteor.method 发送到服务器。
The simplifiedcode below is the part of the client that sends a chunk to the server, it is repeated until offsetreaches data.byteLength:
下面的简化代码是客户端向服务器发送块的部分,它会重复,直到偏移量达到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
The simplifiedcode below is the part on the server that receives the chunk and writes it to the file system :
下面的简化代码是服务器上接收块并将其写入文件系统的部分:
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();
}
});
I failed to write a valid file to the disk, actually the file is saved but I cannot open it, when I see the content in a text editor, it is similar to the original file (a jpg for example) but some characters are different, I think that could be an encoding problem as the file size is not the same, but I don't know how to fix that...
我没有写入有效文件到磁盘,实际上文件已保存但我无法打开它,当我在文本编辑器中看到内容时,它与原始文件(例如jpg)相似,但有些字符不同,我认为这可能是编码问题,因为文件大小不一样,但我不知道如何解决...
回答by Karl.S
Saving the file was as easy as creating a new Buffer with the Uint8Array object :
保存文件就像使用 Uint8Array 对象创建一个新的 Buffer 一样简单:
// chunk is the Uint8Array object
fs.appendFile(path, Buffer.from(chunk), function (err) {
if (err) {
fut.throw(err);
} else {
fut.return(chunk.length);
}
});
回答by toms
Building on Karl.S answer, this worked for me, outside of any framework:
基于Karl.S answer,这对我有用,在任何框架之外:
fs.appendFileSync(outfile, new Buffer(arrayBuffer));
回答by Alex K
Just wanted to add that in newer Meteor you could avoid some callback hell with async/await
. Await will also throw and push the error up to client
只是想在较新的 Meteor 中添加它,您可以避免使用async/await
. 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;
}
});