U盘存了一些文件,向U盘写入一个新文件,在写入还没有完成的过程中,直接拔下U盘,会损坏旧文件吗?
理论上有可能损坏,因为文件系统元数据可能被破坏。
但对于设计水平较高的文件系统、使用设计水平较高的文件系统驱动读写,理论上不会损坏,因为它有日志等辅助设置,可以借此恢复文件系统元数据。
但,哪怕是设计水平极高的日志型文件系统,突然断电带来的异常可能实在太多,程序未必能覆盖所有可能,因此仍然存在文件系统元数据被破坏的可能,继而导致数据丢失。
简单说,一个文件存储进U盘,并不是“一个文件放进去”这么简单,而是包含了一大堆复杂的动作。
首先一个是“分区表”,这个区域常规来说永远不会碰它,除非你重新分区或者修改分区大小。
然后,在每个分区里面还有一个“文件分配表(FAT文件系统术语,其他文件系统可以叫文件系统元数据,知道是什么就行了,我懒得区分它)”,顾名思义,它大致记录了每个文件的名字、第一个数据块存在哪里、后续的数据块到哪找,诸如此类——不同的文件系统格式不同,就不深入探讨了。
那么,你往U盘写入一个新文件,究竟发生了什么呢?
1、在U盘写入文件内容
2、文件写完之后,更新文件分配表
旧的文件系统,比如FAT32,它就这么赤裸裸。所以只要你不是在它“正在更新文件分配表元数据”时突然拔下,那么新文件自然丢了,但旧文件就没事。
但如果你恰好在它“更新文件分配表元数据”时拔下,那么文件分配表就可能出错,导致整个U盘分区无法识别——此时有一些工具可以修复它,但效果有限。
然后,较新的文件系统,比如ntfs/ext4等,它们是日志型文件系统。
什么意思呢?
意思就是,通过日志,把“修改文件分配表”搞成“原子读写”,从而彻底规避“旧数据被突然断电破坏”问题。
具体思路是,先不要改文件分配表,而是先记录当前是什么状态、我要改什么,这些切实写入日志之后,再执行修改动作。那么如果改成功了,文件分配表自然是正确的;但如果没改成功,那就按照日志重做或者回退(但NTFS/EXT4只保证元数据没问题,新文件内容还是可能丢)。
但是,存储系统是非常复杂的,并不仅仅是一个U盘;其上还有Windows等OS的缓存以及硬件控制器缓存等等东西(比如SSD就可能有ftl缓存);所以以上如果每一步都要确认,那要么极慢、要么干脆做不到。
这就造成了更多的复杂性,于是哪怕“原子性修改元数据”也可能出错了——几率很低,但不是没有。
综上,老老实实先“弹出存储器”再拔掉是最安全的;直接拔下,文件系统越老,风险越大。