nfs共享存儲web項目集羣的一次下載流爲空FIleChannel空洞bug

參考:

https://blog.csdn.net/will_awoke/article/details/25972361
http://ifeve.com/file-channel/

FileChannel對象是線程安全(thread-safe)的。多個進程可以在同一個實例上併發調用方法而不會引起任何問題,不過並非所有的操作都是多線程的(multithreaded)。影響通道位置或者影響文件大小的操作都是單線程的(single-threaded)。如果有一個線程已經在執行會影響通道位置或文件大小的操作,那麼其他嘗試進行此類操作之一的線程必須等待。併發行爲也會受到底層的操作系統或文件系統影響。

同大多數I/O相關的類一樣,FileChannel是一個反映Java虛擬機外部一個具體對象的抽象。FileChannel類保證同一個Java虛擬機上的所有實例看到的某個文件的視圖均是一致的,但是Java虛擬機卻不能對超出它控制範圍的因素提供擔保。通過一個FileChannel實例看到的某個文件的視圖同通過一個外部的非Java進程看到的該文件的視圖可能一致,也可能不一致。多個進程發起的併發文件訪問的語義高度取決於底層的操作系統和(或)文件系統。一般而言,由運行在不同Java虛擬機上的FileChannel對象發起的對某個文件的併發訪問和由非Java進程發起的對該文件的併發訪問是一致的。

文件空洞(file hole)
在UNIX文件操作中,文件位移量可以大於文件的當前長度,在這種情況下,對該文件的下一次寫將延長該文件,並在文件中構成一個空洞,這一點是允許的。位於文件中但沒有寫過的字節都被設爲 0。
如果 offset 比文件的當前長度更大,下一個寫操作就會把文件“撐大(extend)”。這就是所謂的在文件裏創造“空洞(hole)”。沒有被實際寫入文件的所有字節由重複的 0 表示。空洞是否佔用硬盤空間是由文件系統(file system)決定的。
用ls查看的文件大小是將空洞算在內的。
cp命令拷貝的文件,空洞部分不拷貝,所以生成的同樣文件佔用磁盤空間小。
用read讀取空洞部分讀出的數據是0,所以如果用read和write拷貝一個有空洞的文件,那麼最終得到的文件沒有了空洞,空洞部分都被0給填充了,文件佔用的磁盤空間就大了。不過文件大小不變。
空洞文件作用很大,例如迅雷下載文件,在未下載完成時就已經佔據了全部文件大小的空間,這時候就是空洞文件。下載時如果沒有空洞文件,多線程下載時文件就都只能從一個地方寫入,這就不是多線程了。如果有了空洞文件,可以從不同的地址寫入,就完成多線程的優勢任務。>

本次bug 最終以判斷是否讀完做了修改,期望不會引起其他問題。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章