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

时间:2013-07-02 16:59:39

标签: java

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

我正在使用Java 8

这样做

据我所知,删除的文件在被覆盖之前一直保留在磁盘上

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

感谢。

2 个答案:

答案 0 :(得分:8)

恢复已删除的文件需要了解底层文件系统的实现方式,因此在您到达任何地方之前,您需要做一些阅读。

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

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

这不是你下午可以做的事情。

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

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

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

在Windows上,您可以从\\.\PhysicalDisk0读取。来自Naming Files, Paths, and Namespaces

  

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

     

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

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

     

大多数API不支持“\\。\”;只有那些旨在使用设备命名空间的设备才能识别它。请务必查看每个API的参考主题。

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

答案 1 :(得分:3)

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

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

删除文件时,要求文件系统从文件表中删除相应的条目。这意味着文件内容确实没有从磁盘上物理删除,如果你足够幸运,可能还原。为什么呢?因为一旦从表中删除了文件条目,就可以重用文件占用的空间,因此可以在那里存储其他信息。

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

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

  1. 以母语实施此任务。
  2. 使用执行此任务的现有工具并提供API或命令行界面。