如題烟具,本文試圖弄清楚這樣一個問題:
如果文件的最后一個block的最后一個chunk里的數(shù)據(jù)不足512字節(jié)梢什,那么還會為其生成checksum么?
先給出答案:會生成朝聋。 接著我們再去探究過程嗡午。
客戶端在發(fā)送數(shù)據(jù)之前,為每一個chunk生成4字節(jié)的checksum冀痕。如果不滿一個chunk荔睹,也是會生成4字節(jié)的checksum的。
相關代碼在FSOutputSummer#writeChecksumChunks
方法里:
此方法作用是為給定data chunks 生成checksum言蛇,然后輸出chunks&checksum僻他。
此方法調(diào)用點有:write1、flushBuffer猜极。
/** Generate checksums for the given data chunks and output chunks & checksums
* to the underlying output stream.
*/
private void writeChecksumChunks(byte b[], int off, int len)
throws IOException {
// DataChecksum對象的方法, 如果NativeCrc32可用中姜,則用native計算,
// 如果NativeCrc32不可用跟伏,則用java.util.zip.Checksum的update方法去計算丢胚。
// 執(zhí)行完這個方法后,參數(shù)checksum字節(jié)數(shù)組會被計算出來的校驗和填充受扳。
sum.calculateChunkedSums(b, off, len, checksum, 0);
TraceScope scope = createWriteTraceScope();
try {
// 這個for循環(huán)就是為每個chunk匹配對應的checksum携龟。writeChunk底層會寫到輸出流的curPacket里。
// curPacket已經(jīng)按照提前計算好的數(shù)據(jù)和checksum字節(jié)數(shù)做了slice勘高。所以這里for循環(huán)的每次迭代都會向DFSPacket里寫入一個chunk和其checksum峡蟋。
for (int i = 0; i < len; i += sum.getBytesPerChecksum()) {
int chunkLen = Math.min(sum.getBytesPerChecksum(), len - i);
int ckOffset = i / sum.getBytesPerChecksum() * getChecksumSize();
writeChunk(b, off + i, chunkLen, checksum, ckOffset,
getChecksumSize());
}
} finally {
if (scope != null) {
scope.close();
}
}
}
再深入了解一點,上面的writeChecksumChunks方法有一處調(diào)用點在flushBuffer里华望。這是個關鍵的方法蕊蝗,它的兩個參數(shù)使我們需要弄懂的。
所以這里又引申出flushBuffer的兩個參數(shù)(文末會有這兩個參數(shù)含義的總結赖舟,可以先去看蓬戚,然后再返回到這里):