關於FileChannel的解釋及用途網絡上的資料已經解釋的很清楚了, 總的概括來說 FileChannel 是 用於讀、寫、映射、維護一個文件的通道, 這里不再贅述
起因▼
FileChannel中提供了兩個方法 transferFrom(ReadableByteChannel src, long position, long count) 和 transferTo(long position, long count, WritableByteChannel target)用於兩個通道間的數據傳輸,通常使用單線程進行傳輸的時候這兩個方法不會出現什么問題, 但是 當我使用多線程方式 進行文件的復制的時候, transferFrom 方法最后傳輸的總是 count的長度(count是每個線程平均分配處理的長度). 這個問題困擾我兩天,並且各處資料都沒有詳細的介紹關於這兩個方法在多線程情況下的問題, 在此做個記錄, 也希望后來者乘涼.
問題復現▼
以下代碼測試兩個方法使用多線程 copy文件
使用transferFrom copy的文件▼
使用transferTo copy的文件▼
上面兩張圖片可以看出, 使用transferFrom copy的文件總是定義的每個線程分配的處理大小 20M, transferTo copy的文件是大小正常且沒有損壞, 具體原因往下看
分析▼
從方法名來看 transferTo 是將當前通道數據寫到另一個通道, transferFrom 是從另一個通道拿數據到當前通道, 通過這個思路思考一下, 是什么原因呢?
transferTo 是將當前通道數據寫到另一個通道, 對象是當前通道, 所以我們不用考慮另一個通道的什么, 我就把文件數據寫給你就行了, 而 transferFrom 是從另一個通道拿數據到當前通道, 在復制文件的情況下, 新建立的當前通道是空白的, 我們只知道要寫到哪個文件,但是不知道文件的大小, 所以默認每一次就從0開始寫入, 從而導致文件最后的大小是線程分配大小. 所以,在建立文件的同時,我們就給它指定一個大小, 然后每一次從指定的位置開始寫入, 那么就可以完整的復制一個文件了
修改上面代碼中的 靜態內部線程類▼
與以上代碼相比,只增加了一行代碼
歡迎關注我的微信公眾號 抓幾個娃 聊點技術,聊點生活
以上