大多數作業系統根本不管複製有沒有出錯,只管複製過程有沒有出錯。這中間是有區別的。得說細一些。
檢查複製沒出錯需要做複製校驗,這事是有幾個層次的。
最直觀的,也是成本最高的,就是把複製過去的東西再拿來讀一遍,和來源全部對照一遍。叫做全讀校驗。很顯然,這是一定能確認複製沒有錯的方法。然而它也很顯然太“貴”了,因為等於源資料要讀至少兩遍,複製資料要讀至少一遍寫至少一遍,相比不檢查多出了許多工作量。而且對很多應用場景來說,這甚至是做不到的。所以大多數作業系統預設不做這種程度的校驗。
為什麼很多場景下做不到?因為複製資料的場景比大多數人直觀想象要複雜得多,簡單直接順利的情景佔不到全部的九成。比如,最令人討厭情況有複製資料到慢速裝置,寫入10Mbps讀取0.1Mbps,全讀校驗花的時間是複製本身的100倍。還有各種複製鎖無法保證的情況。例如源資料在校驗過程中改變了,或者你只有目標的寫許可權沒有讀許可權,或者你的來源資料只能讀一遍的情況。大量常見場景使得全讀校驗無法實現。
不用這種一定能確認複製沒錯的方法,還有什麼別的辦法嗎?那就分好幾種妥協方法了。
有些作業系統採用的妥協省事方法是hash校驗。複製的目標端有某種內建方法生成檔案hash值,複製過程生成源資料的hash值,複製完成時對照一下兩個hash,一致就ok。這是一種比較聰明的低成本近似全讀校驗的辦法。這個方法顯然需要目標支援生成hash的方法,不然就得再讀一遍了,所以適用場景有限。
再弱一些,也就是Windows和大多數作業系統都支援的方法,就是管道可靠性校驗,也就是隻管複製過程有沒有出錯。思路是這樣的:我讀的時候要求讀資料管道確認讀沒出錯,寫的時候要求寫資料管道確認寫沒出錯,那基本的資料一致性就得到保證了。具體實現細節就不展開說了,情景其實也很複雜。只要知道這種校驗其實可以很弱,但總歸比沒有強太多。Windows使用者在複製檔案時看到的CRC迴圈冗餘校驗錯誤實際上就是在寫管道上的校驗機制不能透過報的錯。這種方法也往往是所有其他更復雜校驗的基礎。
為什麼說這種校驗可以很弱呢?因為管道的可驗證性在很多常見條件下是很弱的。有時候甚至管道並沒有辦法去確認有沒有出錯。比如直到SATA年代硬碟的指令才有統一的校驗機制,在此之前很可能你讓硬碟寫資料你是無法判斷硬碟到底有沒有幹這事的。外加這個方法其實不能覆蓋端到端,因為讀出來的資料會停留在記憶體一段時間,而普通的記憶體是沒有資料一致性保護的。所以有少數運氣不好的使用者會發現記憶體損壞導致複製出現錯誤,而複製過程不報錯的現象。
大多數作業系統根本不管複製有沒有出錯,只管複製過程有沒有出錯。這中間是有區別的。得說細一些。
檢查複製沒出錯需要做複製校驗,這事是有幾個層次的。
最直觀的,也是成本最高的,就是把複製過去的東西再拿來讀一遍,和來源全部對照一遍。叫做全讀校驗。很顯然,這是一定能確認複製沒有錯的方法。然而它也很顯然太“貴”了,因為等於源資料要讀至少兩遍,複製資料要讀至少一遍寫至少一遍,相比不檢查多出了許多工作量。而且對很多應用場景來說,這甚至是做不到的。所以大多數作業系統預設不做這種程度的校驗。
為什麼很多場景下做不到?因為複製資料的場景比大多數人直觀想象要複雜得多,簡單直接順利的情景佔不到全部的九成。比如,最令人討厭情況有複製資料到慢速裝置,寫入10Mbps讀取0.1Mbps,全讀校驗花的時間是複製本身的100倍。還有各種複製鎖無法保證的情況。例如源資料在校驗過程中改變了,或者你只有目標的寫許可權沒有讀許可權,或者你的來源資料只能讀一遍的情況。大量常見場景使得全讀校驗無法實現。
不用這種一定能確認複製沒錯的方法,還有什麼別的辦法嗎?那就分好幾種妥協方法了。
有些作業系統採用的妥協省事方法是hash校驗。複製的目標端有某種內建方法生成檔案hash值,複製過程生成源資料的hash值,複製完成時對照一下兩個hash,一致就ok。這是一種比較聰明的低成本近似全讀校驗的辦法。這個方法顯然需要目標支援生成hash的方法,不然就得再讀一遍了,所以適用場景有限。
再弱一些,也就是Windows和大多數作業系統都支援的方法,就是管道可靠性校驗,也就是隻管複製過程有沒有出錯。思路是這樣的:我讀的時候要求讀資料管道確認讀沒出錯,寫的時候要求寫資料管道確認寫沒出錯,那基本的資料一致性就得到保證了。具體實現細節就不展開說了,情景其實也很複雜。只要知道這種校驗其實可以很弱,但總歸比沒有強太多。Windows使用者在複製檔案時看到的CRC迴圈冗餘校驗錯誤實際上就是在寫管道上的校驗機制不能透過報的錯。這種方法也往往是所有其他更復雜校驗的基礎。
為什麼說這種校驗可以很弱呢?因為管道的可驗證性在很多常見條件下是很弱的。有時候甚至管道並沒有辦法去確認有沒有出錯。比如直到SATA年代硬碟的指令才有統一的校驗機制,在此之前很可能你讓硬碟寫資料你是無法判斷硬碟到底有沒有幹這事的。外加這個方法其實不能覆蓋端到端,因為讀出來的資料會停留在記憶體一段時間,而普通的記憶體是沒有資料一致性保護的。所以有少數運氣不好的使用者會發現記憶體損壞導致複製出現錯誤,而複製過程不報錯的現象。