[英]Loop over uploaded files and return an array of file signatures
I want to loop over files selected for upload, get the file signature and return a array of file signatures.我想循环选择要上传的文件,获取文件签名并返回一组文件签名。 The
listOfFileSignatures
array is empty outside the readFirstFourBytes
function. listOfFileSignatures
数组在readFirstFourBytes
function 之外是空的。 Is their a way to make it accessible globally?他们是一种使其在全球范围内可访问的方法吗?
var listOfFileSignatures = [];
var totalSize;
var uploadedFiles = document.getElementById("notes").files;
for (file of uploadedFiles) {
var blob = file;
var fileReader = new FileReader();
fileReader.onloadend = function readFirstFourBytes(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var fileSignature = "";
for (var i = 0; i < arr.length; i++) {
fileSignature += arr[i].toString(16);
};
listOfFileSignatures.push(fileSignature);
console.log(listOfFileSignatures); // Array(3) [ "ffd8ffdb", "ffd8ffe0", "47494638" ]
};
fileReader.readAsArrayBuffer(blob);
};
console.log(listOfFileSignatures); // Array []
You can declare listOfFileSignatures globally, but the signatures are computed asynchronously, so the list will be empty directly after the for loop.您可以全局声明 listOfFileSignatures,但签名是异步计算的,因此在 for 循环之后列表将直接为空。 FileReader is always asynchronous, so you can't avoid that.
FileReader 始终是异步的,因此您无法避免这种情况。 One possibility to handle this is to check if the list is full inside onloadend (
listOfFileSignatures.length == uploadedFiles.length
) and then do what you want there.处理此问题的一种可能性是检查列表是否在 onloadend (
listOfFileSignatures.length == uploadedFiles.length
)内已满,然后在那里执行您想要的操作。
A nicer approach is to use promises, like this:更好的方法是使用 Promise,如下所示:
var uploadedFiles = document.getElementById("notes").files;
Promise.all([...uploadedFiles].map(file => new Promise((resolve, reject) => {
var blob = file;
var fileReader = new FileReader();
fileReader.onloadend = function readFirstFourBytes(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var fileSignature = "";
for (var i = 0; i < arr.length; i++) {
fileSignature += arr[i].toString(16);
};
resolve(fileSignature);
};
fileReader.readAsArrayBuffer(blob);
}))).then(function(listOfFileSignatures) {
// this will be called once, when all results are collected.
console.log(listOfFileSignatures);
});
Additionally, reading all bytes and then select just the first 4 byte is inefficient.此外,读取所有字节,然后读取 select 仅前 4 个字节效率低下。 Improved version:
改良版:
Promise.all([...uploadedFiles].map(file => new Promise((resolve, reject) => {
var blob = file;
var fileReader = new FileReader();
fileReader.onloadend = function readFirstFourBytes(e) {
var arr = new Uint8Array(e.target.result);
var fileSignature = "";
for (var i = 0; i < arr.length; i++) {
fileSignature += arr[i].toString(16);
};
resolve(fileSignature);
};
fileReader.readAsArrayBuffer(blob.slice(0, 4));
}))).then(function(listOfFileSignatures) {
// this will be called once, when all results are collected.
console.log(listOfFileSignatures);
});
fileReader.onload is asynchronous, console.log (listOfFileSignatures); fileReader.onload 是异步的,console.log(listOfFileSignatures); is called before files have been read
在读取文件之前调用
one option is to create an external function that returns a promise, returning the listOfFileSignatures array一种选择是创建一个返回 promise 的外部 function,返回 listOfFileSignatures 数组
function getListFile() {
return new Promise((resolve, reject) => {
var blob = file;
var fileReader = new FileReader();
fileReader.onloadend = function readFirstFourBytes(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var fileSignature = "";
for (var i = 0; i < arr.length; i++) {
fileSignature += arr[i].toString(16);
};
listOfFileSignatures.push(fileSignature);
resolve(listOfFileSignatures);
};
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.