如何使用Java恢复已删除的文件?


问题内容

我想通过Java从磁盘恢复文件而不使用本机库

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

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

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

谢谢。


问题答案:

要恢复已删除的文件,需要了解底层文件系统的实现方式,因此您需要做一些阅读工作,然后才能到达任何地方。

从理论上讲,是的,您绝对可以使用纯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中使用的文件描述符。根本没有工作。