一次一个地使用Javascript FileReader API读取多个文件

xae*_*des 21 javascript html5 filereader fileapi

我正在使用FileReader API来读取多个文件.

<html> <body>
    <input type="file" id="filesx" name="filesx[]"
      onchange="readmultifiles(this.files)" multiple=""/>
    <div id="bag"><ul/></div>
<script>
window.onload = function() {
    if (typeof window.FileReader !== 'function') {
        alert("The file API isn't supported on this browser yet.");
    }
}

function readmultifiles(files) {
    var ul = document.querySelector("#bag>ul");
    while (ul.hasChildNodes()) {
        ul.removeChild(ul.firstChild);
    }

    function setup_reader(file) {
        var name = file.name;
        var reader = new FileReader();
        reader.onload = function(e) {
            var bin = e.target.result; //get file content

            // do sth with text

            var li = document.createElement("li");
            li.innerHTML = name;
            ul.appendChild(li);
        }
        reader.readAsBinaryString(file);
    }

    for (var i = 0; i < files.length; i++) { setup_reader(files[i]); }
}
</script> </body> </html>
Run Code Online (Sandbox Code Playgroud)

问题是所有文件都是同时读取的,当文件的总大小(总和)非常大时,浏览器会崩溃.

我希望一个接一个地读取一个文件,以便减少内存消耗.

这可能吗?

xae*_*des 19

我自己想出了一个有效的解决方案.

function readmultifiles(files) {
  var reader = new FileReader();  
  function readFile(index) {
    if( index >= files.length ) return;
    var file = files[index];
    reader.onload = function(e) {  
      // get file content  
      var bin = e.target.result;
      // do sth with bin
      readFile(index+1)
    }
    reader.readAsBinaryString(file);
  }
  readFile(0);
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么不为每次读取创建一个新的[FileReader](https://developer.mozilla.org/en/docs/Web/API/FileReader)对象?我相信FileReader对象在状态从"0"(空)变为"1"(加载),然后变为"2"(完成)之后不能重复使用.这可能会给你一些严重的浏览器错误. (11认同)

Cer*_*rus 16

这应该逐个读取文件:

function readmultifiles(files) {
    var ul = document.querySelector("#bag>ul");
    while (ul.hasChildNodes()) {
        ul.removeChild(ul.firstChild);
    }
    // Read first file
    setup_reader(files, 0);
}

// Don't define functions in functions in functions, when possible.

function setup_reader(files, i) {
    var file = files[i];
    var name = file.name;
    var reader = new FileReader();
    reader.onload = function(e){
                        readerLoaded(e, files, i, name);
                    };
    reader.readAsBinaryString(file);
    // After reading, read the next file.
}

function readerLoaded(e, files, i, name) {
    // get file content  
    var bin = e.target.result;
    // do sth with text

    var li = document.createElement("li");
    li.innerHTML = name;
    ul.appendChild(li);

    // If there's a file left to load
    if (i < files.length - 1) {
        // Load the next file
        setup_reader(files, i+1);
    }
}
Run Code Online (Sandbox Code Playgroud)


Eri*_*dán 10

使用属性定义输入multiple

<input onchange = 'upload(event)' type = 'file' multiple/>
Run Code Online (Sandbox Code Playgroud)

定义上传函数:

<input onchange = 'upload(event)' type = 'file' multiple/>
Run Code Online (Sandbox Code Playgroud)


adi*_*adi 8

我正在更新此问题,以使新用户受益,他们正在寻找一种通过FileReader API(尤其是使用ES)上传多个文件的解决方案。

与其手动遍历每个文件,不如Object.keys(files)在ES中使用它更加简单和整洁:

<input type="file" onChange="readmultifiles" multiple/>
<script>
function readmultifiles(e) {
  const files = e.currentTarget.files;
  Object.keys(files).forEach(i => {
    const file = files[i];
    const reader = new FileReader();
    reader.onload = (e) => {
      //server call for uploading or reading the files one-by-one
      //by using 'reader.result' or 'file'
    }
    reader.readAsBinaryString(file);
  })
};
</script>
Run Code Online (Sandbox Code Playgroud)

  • Array.from(files).foreach(file =&gt; {}) 也很好用 (3认同)