我希望通过将零写入其物理区域来创建一个文件脱节器来完全删除文件。
文件可能存储在硬盘驱动器中,而不是总是存储在整个块中。
当我说实体区域时。我的意思是文件存储的物理部分,或者我可以执行“写零”的那些部分的任何引用。
更好的C#。
答案 0 :(得分:6)
不幸的是,即使您正在编写内核模式驱动程序,在C#中也不是完全可能的,在C / C ++中也是如此。
的引用正确地粉碎单个文件假定其位置可以完全知道,但基本上它只能在一个理想情况下知道。理想情况有三个特征:
- 由于编辑,文件大小从未缩小。 想象一下,从3MB电子表格开始,将其编辑为1MB(使用电子表格应用程序),并询问清洁工应用程序删除1MB版本:清理工具无法知道在物理硬盘驱动器上分配丢失的2MB的位置。 (请记住:文件系统通常不会连续存储文件,所以你不能假设缺失的部分直接在已知部分之后。)
- 文件从未移动。 想象一下,电子表格软件通过将新副本写入临时文件,删除旧副本以及将临时文件重命名为临时文件来保存文档原名。在这种情况下,清理器应用程序无法知道任何旧电子表格的位置。
- 文件系统会将文件覆盖到同一个地方。 这是一个很好的假设。在Windows NTFS和Linux上,最常见的ext3配置(在Ubuntu 9.10和其他Linux发行版上是默认配置)会在同一位置覆盖文件,但透明磁盘压缩,加密和稀疏文件可能无法覆盖文件。
醇>
此外:当现代硬盘驱动器的某个区域损坏时,它会自动将坏扇区重新映射到备用区域。这些操作由驱动器的固件决定,操作系统和应用程序都不知道移动,因此擦除驱动器会忽略损坏的区域。
话虽如此,但有可能(尽管不容易)找出当前 文件占用的驱动器的哪些扇区。但是,这要求您的应用程序(至少部分地)了解所使用的文件系统以及该文件系统如何在底层介质上存储文件。
最后,问题仍然是通过识别文件所占用的所有扇区并将其填充为0而不仅仅是
来获得额外的安全性。using(var fs = new System.IO.FileStream(@"m:\delme.zip",
FileMode.Open,
FileAccess.Write,
FileShare.None))
{
var zeros = new byte[fs.Length];
fs.Write(zeros, 0, zeros.Length);
}
答案 1 :(得分:1)
通常,没有.NET API。很可能你正在考虑从磁盘手动读取FS结构并解析文件分配结构并使用interop转到低级块IO。
您可能希望尝试将零写入文件而不更改其长度并观察发生的情况。有可能不会重新分配文件。我真的不知道是不是这种情况,我怀疑它取决于操作系统,操作系统版本,FS,甚至可能在SSD和硬盘驱动器之间有所不同。
此外,考虑最近您的操作系统重新分配您正在尝试粉碎的文件的情况。文件使用的某些区域现在标记为“空”,但数据仍然存在。 (几乎)没有办法弄清楚这些区域是什么/没有实际“粉碎”整个磁盘。
此外,对于我们中间的偏执狂:将零(或者一些或垃圾)写入文件区域并不能保证旧数据不可恢复。物理上破坏驱动器可能会有所作为,但没有API;)
答案 2 :(得分:0)
我不确定你能做到这一点。 根据{{3}},您只能使用非托管代码来执行此操作。