1

FileReader API を使用してバイナリデータのスライスをサーバーに送信する流星アプリをコーディングしました。

クライアント側でスライスを処理するメソッド:

var readSlice = function() {
    var start, end;

    start = chunk * chunkSize;

    if (start > file.size) {
        start = end + 1;
    }

    end = start + (chunkSize - 1) >= file.size ? file.size : start + (chunkSize - 1);

    fileReader.onload = function(event) {
        if (++chunk <= chunks) {
            Meteor
                .apply("saveChunk", [ event.target.result.split(',')[1], file.name, clientRegistration, now, (chunk === chunks) ], {
                    wait : true
                });

            readSlice();
        } else {
            /*
             * TODO Notify the GUI
             */
            console.log("reading done");
        }
    };

    fileReader.readAsDataURL(blobSlice.call(file, start, end));
};

スライスはサーバーによって適切な順序で受信され、次の方法でマージされます。

saveChunk : function(chunk, name, registration, timestamp, last) {

    ...

    tempFile = Meteor.fileTemp + "/" + identifier;

    fs.appendFile(tempFile, new Buffer(chunk, "base64"), {
    encoding : "base64",
    mode : 438,
    flag : "w"
    }, function(error) {
        if (error) {
            throw (new Meteor.Error(500, "Failed to save file.", err));
        }
    });
}

このプロセスはほとんど問題なく動作します。ただし、これらはファイルの小さな違いであり、出力が破損する原因となります。バイナリの違いは、出力が分割されたファイル内のポイントで発生するため、event.target.resultプロパティの分割呼び出しに問題があるか、エンコーディングに関して明らかな何かが欠けている可能性があります...?

マージされたファイルと元のファイルの差分が次の興味深いパターンを示しているため、問題は分割に関連しているようです。

マージされたファイルのパターン

4

1 に答える 1

1

破損したデータは、単純な計算ミスの結果でした:

使用する

end = (start + chunkSize ) >= file.size ? file.size : (start + chunkSize);

それ以外の

end = start + (chunkSize - 1) >= file.size ? file.size : start + (chunkSize - 1);

問題を修正しました。

于 2013-11-20T11:01:13.520 に答える