如何在 JS 中从 ArrayBuffer 写入文件
Posted
技术标签:
【中文标题】如何在 JS 中从 ArrayBuffer 写入文件【英文标题】:How to write a file from an ArrayBuffer in JS 【发布时间】:2015-10-13 09:33:23 【问题描述】:我正在尝试为 Meteor 框架编写文件上传器。 原理是将客户端上的文件从一个ArrayBuffer中拆分成4096位的小包,通过Meteor.method发送到服务器。
下面的简化代码是客户端向服务器发送块的部分,它会重复直到offset达到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)但有些字符不同,我认为这可能是编码问题,因为文件大小不一样,但我不知道如何解决...
【问题讨论】:
你能改为传递一个 blob 吗?它们通常作为缓冲区出现在节点中,由 fs.AppendFile() 处理。 @dandavis 其实你给了我一半的答案,毕竟解决方案很简单,谢谢! 【参考方案1】:以Karl.S answer 为基础,这对我有用,在任何框架之外:
fs.appendFileSync(outfile, Buffer.from(arrayBuffer));
【讨论】:
不推荐使用新缓冲区。请改用 Buffer.from(arrayBuffer)。 不推荐使用同步版本的 I/O 函数,因为它会阻塞事件循环,除非你有理由这样做。【参考方案2】:保存文件就像使用 Uint8Array 对象创建一个新的缓冲区一样简单:
// chunk is the Uint8Array object
fs.appendFile(path, Buffer.from(chunk), function (err)
if (err)
fut.throw(err);
else
fut.return(chunk.length);
);
【讨论】:
new Buffer(chunk) 不推荐使用 Buffer.from(chunk)【参考方案3】:只是想在较新的 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;
);
【讨论】:
以上是关于如何在 JS 中从 ArrayBuffer 写入文件的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Django 中从 JavaScript 调用 Python 函数?
哪位朋友使用过js中的ArrayBuffer,请教一个转换问题
如何在 Flutter 中从 firebase 存储读取和写入文本文件?
如何在 Javascript/Node 中从 blob 写入 .wav 文件