C# 如何获取硬盘上的文件物理位置

C# 如何获取硬盘上的文件物理位置,c#,file,delete-file,erase,drive,C#,File,Delete File,Erase,Drive,我想通过将零写入文件的物理区域,使文件完全删除 文件可能以片段的形式存储在硬盘上,而不总是以整个块的形式存储 当我说物理区域时。我指的是文件存储的物理部分,或者我可以执行“写零”操作的对这些部分的任何引用 C#更好 我不确定你能做到这一点。 根据,您只能使用非托管代码来执行此操作。不幸的是,这在C#中并不完全可行,在C/C++中也不完全可行,即使您正在编写内核模式驱动程序 引自 正确分解单个文件假定其位置可以完全知道,但基本上只能在一种理想情况下知道。理想情况有三个特征: 文件大小从未因编辑而缩

我想通过将零写入文件的物理区域,使文件完全删除

文件可能以片段的形式存储在硬盘上,而不总是以整个块的形式存储

当我说物理区域时。我指的是文件存储的物理部分,或者我可以执行“写零”操作的对这些部分的任何引用


C#更好

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

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

引自

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

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

    通常,没有用于此的.NETAPI。最有可能的情况是,您正在从磁盘手动读取FS结构,解析文件分配结构,并使用interop转到低级块IO

    您可能希望尝试将零写入文件,而不更改其长度并观察发生的情况。很可能该文件不会被重新分配。我真的不知道情况是否如此,我怀疑这取决于操作系统、操作系统版本、FS,甚至SSD和HDD之间的差异

    也可以考虑一下,当你试图撕碎的文件最近被OS重新分配的时候。文件使用的某些区域现在标记为“空”,但数据仍然存在。如果不“切碎”整个磁盘,就(几乎)无法确定这些区域是/曾经是什么


    此外,对于我们当中的偏执狂来说:将零(或1,或垃圾)写入文件区域并不保证旧数据变得不可恢复。物理破坏驱动器可能会达到目的,但没有API;)

    我很确定你不能单独用.NET来做这件事,你必须使用一些低级调用来做这件事。你为什么要自己写这个?市场上已经有很多这样的公用事业公司。顺便说一句,仅在现有扇区上写入零并不能完全擦除文件-一些软件仍然能够检索(部分)数据。从用户模式无法写入物理扇区,需要内核模式驱动器。我查看了市场上的一些软件,发现它们不好。你能告诉我们为什么写零不好用吗?你有什么建议?感谢文件系统是一个抽象的系统。您不能在用户模式下执行此操作的原因是,它从来都不是必需的。你唯一需要做的就是如果你正在编写驱动程序,而这在C#中是不会做的。很棒的想法。我喜欢跳出框框思考的方式!谢谢。谢谢你的夸奖。=)谢谢你的回复。我想知道为什么不能保证?一个空间能容纳两段数据吗?@Feng硬盘基本上是带电的金属片。你们可以从一个拆开的硬盘读取剩余电荷,并从中重建数据(昂贵的机器和所需的技能,ofc),即使它被反复覆盖。