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
プロパティの分割呼び出しに問題があるか、エンコーディングに関して明らかな何かが欠けている可能性があります...?
マージされたファイルと元のファイルの差分が次の興味深いパターンを示しているため、問題は分割に関連しているようです。