百科问答小站 logo
百科问答小站 font logo



Windows 等操作系统是如何做到复制大文件不出错的? 第1页

  

user avatar   suan-le-ba 网友的相关建议: 
      

大多数操作系统根本不管复制有没有出错,只管复制过程有没有出错。这中间是有区别的。得说细一些。

检查复制没出错需要做复制校验,这事是有几个层次的。

最直观的,也是成本最高的,就是把复制过去的东西再拿来读一遍,和来源全部对照一遍。叫做全读校验。很显然,这是一定能确认复制没有错的方法。然而它也很显然太“贵”了,因为等于源数据要读至少两遍,拷贝数据要读至少一遍写至少一遍,相比不检查多出了许多工作量。而且对很多应用场景来说,这甚至是做不到的。所以大多数操作系统默认不做这种程度的校验。

为什么很多场景下做不到?因为复制数据的场景比大多数人直观想象要复杂得多,简单直接顺利的情景占不到全部的九成。比如,最令人讨厌情况有复制数据到慢速设备,写入10Mbps读取0.1Mbps,全读校验花的时间是复制本身的100倍。还有各种复制锁无法保证的情况。例如源数据在校验过程中改变了,或者你只有目标的写权限没有读权限,或者你的来源数据只能读一遍的情况。大量常见场景使得全读校验无法实现。

不用这种一定能确认复制没错的方法,还有什么别的办法吗?那就分好几种妥协方法了。

有些操作系统采用的妥协省事方法是hash校验。复制的目标端有某种内置方法生成文件hash值,复制过程生成源数据的hash值,复制完成时对照一下两个hash,一致就ok。这是一种比较聪明的低成本近似全读校验的办法。这个方法显然需要目标支持生成hash的方法,不然就得再读一遍了,所以适用场景有限。

再弱一些,也就是Windows和大多数操作系统都支持的方法,就是管道可靠性校验,也就是只管复制过程有没有出错。思路是这样的:我读的时候要求读数据管道确认读没出错,写的时候要求写数据管道确认写没出错,那基本的数据一致性就得到保证了。具体实现细节就不展开说了,情景其实也很复杂。只要知道这种校验其实可以很弱,但总归比没有强太多。Windows用户在复制文件时看到的CRC循环冗余校验错误实际上就是在写管道上的校验机制不能通过报的错。这种方法也往往是所有其他更复杂校验的基础。

为什么说这种校验可以很弱呢?因为管道的可验证性在很多常见条件下是很弱的。有时候甚至管道并没有办法去确认有没有出错。比如直到SATA年代硬盘的指令才有统一的校验机制,在此之前很可能你让硬盘写数据你是无法判断硬盘到底有没有干这事的。外加这个方法其实不能覆盖端到端,因为读出来的数据会停留在内存一段时间,而普通的内存是没有数据一致性保护的。所以有少数运气不好的用户会发现内存损坏导致复制出现错误,而复制过程不报错的现象。


user avatar    网友的相关建议: 
      

文件按byte为单位复制,每复制1byte做个检验,这样一个byte一个byte的校验可以保证没错,原理是这样,实际上可能是多少bit来一次校验码,海明码了解一下,windows下硬盘到硬盘和硬盘到网络到硬盘之间拷贝方式是没差的。

特别大的直接走DMA(前提是驱动器支持,现在硬盘基本上都支持),这样两个驱动器之间直接对拷,DMA控制器集成校验单元可以直接边传输边校验所以不用担心出错问题。




  

相关话题

  Windows系统中软件的默认安装目录为何是Program Files这个名字? 
  如何评价知乎想法中「人工智能是否能做艺术创新」这一场论战? 
  有哪些IT人才懂的梗? 
  互联网的下一个趋势是什么? 
  为什么win7,win10很多人用,win8,win8.1却无人问津? 
  如何让两台 PC 进行文件传输? 
  如何让两台 PC 进行文件传输? 
  为什么当年的汉芯造假事件没有任何人受到惩处? 
  C的结构体成员变量的命名有必要加前缀吗? 
  当页表中的页表项大部分都有效的时候,多级页表还能节省空间吗? 

前一个讨论
为什么连离我很远很远的服务器会很慢?
下一个讨论
为什么电脑 CPU 不像手机 SoC 那样设计成大小核?





© 2024-11-24 - tinynew.org. All Rights Reserved.
© 2024-11-24 - tinynew.org. 保留所有权利