我想通过Java从磁盘恢复文件而不使用本机库
我正在使用Java 8
这样做据我所知,删除的文件在被覆盖之前一直保留在磁盘上
我可以直接访问linux上的磁盘,我可以读取原始数据,但是,我如何解析ext4或NTFS文件系统上的已删除文件?
感谢。
答案 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。
因此,您有以下解决方案。