2012-01-10 61 views
4

我想通过向其物理区域写入零来完成删除文件的工作。如何在硬盘上获取文件物理位置

文件可能存储在硬盘上,并不总是在整个块中。

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

C#中更好。

+1

我敢肯定,你不能单独使用.NET来做这件事,你将不得不使用一些低级调用来做这个。 – Kolky 2012-01-10 08:11:02

+1

为什么你想自己写这个?有许多公用事业公司已经在市场上做到了这一点。顺便说一句,在现有的扇区上写零不会完全擦除文件 - 某些软件仍然能够检索(部分)数据。 – 2012-01-10 08:14:02

+0

写入物理扇区不可能从用户模式,需要一个内核模式驱动程序 – 2012-01-10 08:14:50

回答

6

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

报价碎纸一个单独的文件正确假定它的位置可以完全清楚,但基本上只能在一个理想的case.The理想的情况下被称为有三个特点:

  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);  
} 
+0

伟大的思想。我喜欢想出来的方式!谢谢。 – Frank 2012-01-10 08:33:44

+0

感谢您的夸奖。 =) – afrischke 2012-01-10 09:00:03

0

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

1

一般来说,没有用于此的.NET API。很可能你正在从磁盘手动读取FS结构并解析文件分配结构,并使用互操作来转到低级块IO。

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

此外,请考虑最近由操作系统重新分配您试图碎化的文件的情况。该文件使用的某些区域现在标记为“空”,但数据仍然存在。 (几乎)没有办法找出这些区域是什么/没有真正“切碎”整个磁盘。

另外,对于我们之间的偏执狂来说:在文件区写入零(或一个,或垃圾)并不能保证旧数据不可恢复。物理上破坏驱动器可能会诀窍,但没有API;)

+0

感谢您的回复。我想知道为什么不能保证?空间可以容纳两块数据吗? – Frank 2012-01-10 08:36:37

+1

@Feng硬盘基本上是带电的金属片。你*可以*从拆卸的硬盘读取剩余电量,并重新构建数据(即所需的昂贵机器和技能,ofc),即使它被重复覆盖。 – Alex 2012-01-10 10:24:25

相关问题