简体   繁体   English

循环上传文件并返回一组文件签名

[英]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 [] 

Heres the output继承人 output

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.

相关问题 按要上传的文件大小对文件数组进行分组 - Group array of files by file size to be uploaded 循环对象数组返回一个数组 - Loop over an array of objects return an array 为什么不会从多个文件(使用html5文件阅读器上传)中推送文本的函数返回数组 - why wont function which pushes text from multiple files (uploaded using html5 file reader) return the array 循环遍历数组并返回数组中每个元素的数组 - Loop over an array and return an array of each element in the array XMLHttpRequest() 不发送 FormData() 导致 PHP $_FILES 数组为空且未上传文件 - XMLHttpRequest() not sending FormData() resulting in empty PHP $_FILES array and no file uploaded 循环遍历对象并累积返回数组中每个键的长度 - Loop over Object and return the length of each key cumulatively in an array 以JSON格式返回上传的文件内容 - Return the uploaded file contents as JSON 循环遍历 Javascript 中具有不同签名的函数数组的最佳实践? - Best practice to loop through an array of Functions with different signatures in Javascript? 我正在尝试遍历目录及其子文件夹中的所有文件,获取每个文件的文本内容并返回一个文本内容数组 - I'm trying to loop through all files in directory & its subfolders, get each file's text content & return an array of text content 无法遍历数组 - unable to loop over an array
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM