2012-12-20 10 views
19

私はFileReader APIを使用して複数のファイルを読み取ります。一度に1つずつJavascript 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> 

問題は、すべてのファイルが同時に読み込まれることで、ファイルが非常に大きい合計サイズ(合計)を持っている場合、ブラウザがクラッシュします。

ファイルを1つずつ読み込み、メモリ消費量を減らしたいです。

これは可能ですか?

答えて

14

私は自分自身がどの作品解決策を考え出しました。

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); 
} 
+9

なぜあなたは新しい[FileReaderの](httpsを作成しないでください://開発者を.mozilla.org/ja/docs/Web/API/FileReader)の各オブジェクトを読み取りますか? FileReaderオブジェクトは、状態が '0'(空)から' 1'(ロード)に変更された後、 '2'(完了)に変更された後に再利用されるものではないと思います。これにより、深刻なブラウザのバグが発生する可能性があります。 – Pacerier

15

これは、ファイルを一つずつ読んでください:

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); 
    } 
} 
+0

素晴らしい答え... –

3

私は特にESを使用して、the FileReader APIを介して複数のファイルをアップロードするためのソリューションを探している新規ユーザーの利益のためにこの質問を更新しています。

のではなく、手動で各ファイルを反復処理、それはObject.keys(files) in 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>