4

我想在不使用本机库的情况下通过 Java 从磁盘中恢复文件

我正在使用 Java 8 执行此操作

据我所知,删除的文件会保留在磁盘上,直到它们被覆盖

我可以直接访问 linux 上的磁盘并且可以读取原始数据,但是,例如,如何解析 ext4 或 NTFS 文件系统上的已删除文件?

谢谢。

4

2 回答 2

10

恢复已删除的文件需要了解底层文件系统是如何实现的,因此您需要先阅读一些内容才能到达任何地方。

理论上,是的,你绝对可以在纯 Java 中做到这一点;您只需要了解如何绕过文件系统从原始磁盘读取数据。在 Unix 系统上,这很简单:将设备节点作为文件打开(您需要root权限)然后读取。在 Windows 上可能有类似的过程;在最坏的情况下,您必须在 C 或 C++ 中创建一个帮助程序库来为您读取数据。

访问原始数据后,查找文件在特定文件系统中的存储方式,并开始在您读取的数据中寻找类似的模式。

不过,这不是你可以在一个下午做的事情。

更新:如何绕过文件系统。

在 Unix 系统上,您可以像这样从分区或卷中读取:

InputStream sda1 = new FileInputStream("/dev/sda1");
int firstByte = sda1.read();

在 Windows 上,您将从 \\.\PhysicalDisk0. 从命名文件、路径和命名空间

使用 Win32 设备命名空间的另一个示例是使用CreateFile带有“\\.\PhysicalDiskX”(其中 X 是有效整数值)或“\\.\CdRomX”的函数。这允许您绕过文件系统直接访问这些设备。这是因为这些设备名称是由系统在枚举这些设备时创建的,并且一些驱动程序还会在系统中创建其他别名。例如,实现名称“C:\”的设备驱动程序有自己的命名空间,它也恰好是文件系统。

通过该CreateFile函数的 API 通常使用“\\.\”前缀,因为CreateFile该函数用于打开文件和设备,具体取决于您使用的参数。

如果您正在使用 Windows API 函数,您应该使用“\\.\”前缀来仅访问设备而不是文件。

大多数 API 不支持 "\\.\"; 只有那些设计用于设备名称空间的人才能识别它。请务必检查每个 API 的参考主题。

我不知道 Java API 是否是使用实现的,CreateFile或者它是否进行了一些名称修改,这意味着您无法访问设备名称空间。在最坏的情况下,您必须创建一个包装库来调用CreateFile并将它返回的 HANDLE 转换为可以在 Java 中使用的文件描述符;这根本不是工作。

于 2013-07-02T17:09:12.630 回答
3

根据定义,文件是存储在永久存储设备上的命名字节序列。文件由名为文件系统的操作系统组件管理。文件系统使用术语“文件”进行操作,并将该术语转换为较低级别的术语,如卷、扇区、块等。

文件名(和路径)与磁盘上实际存储信息的块之间的映射称为文件表,并由文件系统管理。

当您删除文件时,您要求文件系统从文件表中删除适当的条目。这意味着文件内容实际上并没有从磁盘中删除,如果你足够幸运,可能可以恢复。为什么可能?因为一旦从表中删除文件条目,文件占用的空间就可以重新使用,因此其他信息可以存储在那里。

有一些工具可以尝试恢复信息。这些工具在文件系统下工作,即使用较低级别的 API。可能他们正在直接与司机交谈。Java 不提供执行此操作的 API。

因此,您有以下解决方案。

  1. 用母语执行此任务。
  2. 使用执行此任务并提供 API 或命令行界面的现有工具。
于 2013-07-02T17:10:42.997 回答