如何在硬盘上获取文件物理位置

我想通过将零写入其物理区域来制作文件脱粒器以完全删除文件。

文件可以分段存储在硬盘驱动器上,而不是总是存储在整个块中。

当我说实物区。 我的意思是文件存储的物理部分,或者我可以执行“写零”的那些部分的任何引用。

更好的C#。

不幸的是,即使您正在编写内核模式驱动程序,这在C#中也不是完全可能的,在C / C ++中也是如此。

从Bleachbit文档中引用:

正确地粉碎单个文件假定其位置可以完全已知,但基本上只能在一个理想情况下知道。理想情况有三个特征:

  1. 由于编辑,文件大小从未缩小。 想象一下,从3MB电子表格开始,将其编辑为1MB(使用电子表格应用程序),并要求清洁应用程序删除1MB版本:清理工具无法知道在物理硬盘驱动器上分配丢失的2MB的位置。 (请记住:文件系统通常不会连续存储文件,因此您无法假设缺失的部分直接位于已知部分之后。)
  2. 该文件从未移动过。 想象一下,电子表格软件通过将新副本写入临时文件,删除旧副本以及将临时文件重命名为原始名称来保存文档。 在这种情况下,清理器应用程序无法知道任何旧电子表格的位置。
  3. 文件系统将文件覆盖到同一位置。 这是一个很好的假设。 在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); } 

通常,没有.NET API。 您很可能正在考虑从磁盘手动读取FS结构并解析文件分配结构并使用interop转到低级块IO。

您可能希望尝试将零写入文件而不更改其长度并观察发生的情况。 机会是不会重新分配的文件。 我真的不知道是不是这种情况,我怀疑它取决于操作系统,操作系统版本,FS,甚至可能在SSD和硬盘驱动器之间有所不同。

另外,考虑一下您最近尝试粉碎的文件已被操作系统重新分配的情况。 文件使用的某些区域现在标记为“空”,但数据仍然存在。 (几乎)没有办法弄清楚这些区域是什么/没有实际“粉碎”整个磁盘。

此外,对于我们中间的偏执狂:将零(或者一些或垃圾)写入文件区域并不能保证旧数据不可恢复。 物理上破坏驱动器可能会有所作为,但没有API;)

我不确定你能做到这一点。 根据This ,您只能使用非托管代码来执行此操作。