如何从java访问磁盘上的特定原始数据

时间:2010-01-21 10:10:51

标签: java drive

我正在尝试使用以下代码访问原始磁盘中偏移量为50字节的一个字节。

randomAccessFile = new RandomAccessFile("C:", "r");
randomAccessFile.seek(50);
byte[] buffer = new byte[1];
randomAccessFile.read(buffer);

但我得到的是以下错误:

java.io.FileNotFoundException: C: (Acceso denegado)
at java.io.RandomAccessFile.open(Native Method)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:212)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:98)
at pru.lseek.main(lseek.java:26)

有没有办法从java访问驱动器中的精确字节?

8 个答案:

答案 0 :(得分:16)

我一直在寻找从物理驱动器访问原始数据的可能性。现在,当我开始工作时,我只想告诉你如何。您可以直接从java中访问原始磁盘数据...只需使用管理员权限运行以下代码:

    File diskRoot = new File ("\\\\.\\PhysicalDrive0");
    RandomAccessFile diskAccess = new RandomAccessFile (diskRoot, "r");
    byte[] content = new byte[1024];
    diskAccess.readFully (content);

因此,您将获得系统上第一个物理驱动器的第一个kB。要访问逻辑驱动器 - 如上所述 - 只需将“PhysicalDrive0”替换为驱动器号,例如'D:

哦,是的...我在Win 7系统上尝试使用Java 1.7 ......

只需查看http://support.microsoft.com/kb/100027/en-us

的物理驱动器命名

答案 1 :(得分:10)

如果您对Windows下的原始卷编写感兴趣,请尝试此操作(需要Java 7)。

  String pathname;
  // Full drive:
  // pathname = "\\\\.\\PhysicalDrive0";
  // A partition (also works if windows doesn't recognize it):
  pathname = "\\\\.\\GLOBALROOT\\ArcName\\multi(0)disk(0)rdisk(0)partition(5)";

  Path diskRoot = ( new File( pathname ) ).toPath();

  FileChannel fc = FileChannel.open( diskRoot, StandardOpenOption.READ,
        StandardOpenOption.WRITE );

  ByteBuffer bb = ByteBuffer.allocate( 4096 );

  fc.position( 4096 );
  fc.read( bb );
  fc.position( 4096 );
  fc.write( bb );

  fc.close();

当然,您必须确保设备是可写的,而不是系统访问/锁定。还要确保您的应用程序以必要的权限(提升的权限)运行。

顺便说一句:使用new RandomAccessFile(drive, "rw")似乎不起作用,因为Java没有以与原始设备兼容的模式打开文件句柄(例外是java.io.FileNotFoundException (The parameter is incorrect))。但阅读也适用于RandomAccessFile

答案 2 :(得分:4)

RandomAccessFile并不意味着打开目录来操纵条目,您需要创建或删除文件。 “Acceso denegado”可能意味着拒绝访问。 无论如何要做到这一点你需要JNI。

编辑:你要做的事情,真的很复杂,没有共同的方法可以做到这一点。你可以按扇区访问harddisc扇区,但是你必须解释它的结构,这显然取决于文件系统,FAT,NTFS,HPFS等。

答案 3 :(得分:3)

在Linux下,您可以尝试打开/dev/<device>,例如/dev/hda/dev/sdb2。这将使您可以访问原始磁盘(或仅限分区),但要求您具有适当的权限 - “普通”用户不具备这些权限。

答案 4 :(得分:1)

在unix中,您可以从/dev文件读/写。 (我不确定)

在Windows中,我认为您需要通过JNI(Java Native Interface)读/写磁盘扇区。调用一些C库与操作系统通信。

更新:在C库中,您可能需要使用Win32API来获取示例CreateFile(..)函数的文件句柄。

https://metacpan.org/pod/Win32API::File

http://jan.newmarch.name/ssw/files/win32.html

答案 5 :(得分:1)

Java只能访问文件。 Unix将“原始设备”的概念作为/ dev目录中的文件,因此您可以在那里获得所需的内容。但不是在Windows上,因为它没有原始高清数据的这种文件表示。

答案 6 :(得分:1)

在Windows中,您需要将原始设备标识符作为文件进行访问。如果你传入文件“\\。\ c:”,你应该使用设备UNC名称\。\ c :( \。表示这台机器)。

对于Vista以及后来我认为它不会正常工作,因为有一些机制可以阻止对设备驱动程序之外的任何其他设备进行原始访问(不要引用我的信息)

答案 7 :(得分:1)

@hunsricker:请注意,访问原始设备需要一些权限(取决于驱动器:可移动或不移动/取决于WinXP的文件系统:允许使用iso9660,FAT不允许)。

另请注意,读取的大小确实很重要(取决于操作系统): 在iso9660文件系统上,读取(1024字节)在XP上工作但在Seven上失败。 在Seven上看起来,读取必须是块对齐的:read(2048字节)可以工作。