文件不能粘贴复制
复制文件时出错是怎么回事?
复制文件时出错是怎么回事?
大多数操作系统根本不管复制有没有出错,只管复制过程有没有出错。这中间是有区别的。得说细一些。
检查复制没出错需要做复制校验,这事是有几个层次的。
最直观的,也是成本最高的,就是把复制过去的东西再拿来读一遍,和来源全部对照一遍。叫做全读校验。很显然,这是一定能确认复制没有错的方法。然而它也很显然太“贵”了,因为等于源数据要读至少两遍,拷贝数据要读至少一遍写至少一遍,相比不检查多出了许多工作量。而且对很多应用场景来说,这甚至是做不到的。所以大多数操作系统默认不做这种程度的校验。
为什么很多场景下做不到?因为复制数据的场景比大多数人直观想象要复杂得多,简单直接顺利的情景占不到全部的九成。比如,最令人讨厌情况有复制数据到慢速设备,写入10Mbps读取0.1Mbps,全读校验花的时间是复制本身的100倍。还有各种复制锁无法保证的情况。例如源数据在校验过程中改变了,或者你只有目标的写权限没有读权限,或者你的来源数据只能读一遍的情况。大量常见场景使得全读校验无法实现。
不用这种一定能确认复制没错的方法,还有什么别的办法吗?那就分好几种妥协方法了。
有些操作系统采用的妥协省事方法是hash校验。复制的目标端有某种内置方法生成文件hash值,复制过程生成源数据的hash值,复制完成时对照一下两个hash,一致就ok。这是一种比较聪明的低成本近似全读校验的办法。这个方法显然需要目标支持生成hash的方法,不然就得再读一遍了,所以适用场景有限。
再弱一些,也就是Windows和大多数操作系统都支持的方法,就是管道可靠性校验,也就是只管复制过程有没有出错。思路是这样的:我读的时候要求读数据管道确认读没出错,写的时候要求写数据管道确认写没出错,那基本的数据一致性就得到保证了。具体实现细节就不展开说了,情景其实也很复杂。只要知道这种校验其实可以很弱,但总归比没有强太多。Windows用户在复制文件时看到的CRC循环冗余校验错误实际上就是在写管道上的校验机制不能通过报的错。这种方法也往往是所有其他更复杂校验的基础。
为什么说这种校验可以很弱呢?因为管道的可验证性在很多常见条件下是很弱的。有时候甚至管道并没有办法去确认有没有出错。比如直到SATA年代硬盘的指令才有统一的校验机制,在此之前很可能你让硬盘写数据你是无法判断硬盘到底有没有干这事的。外加这个方法其实不能覆盖端到端,因为读出来的数据会停留在内存一段时间,而普通的内存是没有数据一致性保护的。所以有少数运气不好的用户会发现内存损坏导致复制出现错误,而复制过程不报错的现象。
文件无法复制,粘贴,文件打不开?
这跟操作系统(文件系统驱动)有一定关系,但不是绝对相关,跟复制文件的工具有很大关系。
复制文件实际上是一种用户态的应用程序行为,具体的做法就是读文件-写文件。
如果复制工具在用户中断复制时就删除目标文件,那么你就看不到目标文件。 如果复制工具在用户中断复制时不删除目标文件,那么你就可能看到半个文件。 如果复制工具是先创建一个跟源文件一样大的空文件,再慢慢填充(实际情况中很少有工具这么干),那么你就看到一个10G但实际内容不全的文件。
中断复制的后续动作是用户态的复制工具的行为,跟操作系统无关。
跟操作系统有关的是复制时掉电,但这个要分析起来就很麻烦了,也要看复制工具的代码具体怎么写的,有些工具可能开了一个巨大的cache,写满以后flush一下,有的则是一小块一小块的写。
对于使用了巨大的cache的复制工具,如果文件系统没有采用自动修复的动作,那么你可能看到一个长度是0或者长度是10G或者长度是一个cache倍数之类的文件,但内容未必全写进去。
如果是一小块一小块的写,看到的文件大小跟写进去的内容基本上差不太多,对于视频来说,可能是可以放出一部分的。
掉电时的文件系统行为跟文件系统格式、文件系统驱动行为有关系。
至于你的视频能不能看,那是还要跟视频本身的格式有关系。