18

我正在尝试使用以下代码访问原始磁盘中偏移量为 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访问驱动器中的精确字节?

4

8 回答 8

18

我一直在寻找从物理驱动器访问原始数据的可能性。现在,当我开始工作时,我只想告诉你如何做。您可以直接从 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上查看物理驱动器的命名

于 2011-12-22T22:14:59.540 回答
13

如果您有兴趣在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 ); // careful!

  fc.close();

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

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

于 2013-11-01T09:25:19.203 回答
4

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

编辑:你想要做的事情真的很复杂,没有通用的方法可以做到这一点。您可以逐个扇区访问硬盘,但是您必须解释它的结构,这显然取决于文件系统、FAT、NTFS、HPFS 等。

于 2010-01-21T10:20:02.297 回答
3

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

于 2010-01-21T10:18:56.563 回答
1

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

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

于 2012-02-22T08:18:09.107 回答
1

在 Windows 中,您需要将原始设备标识符作为文件访问。如果您传入文件“\\.\c:”,它应该可以工作,您使用的是设备 UNC 名称 \.\c:(\. 表示本机)。

对于 Vista 和更高版本,我认为它不能正常工作,因为有机制可以防止设备驱动程序以外的任何东西对磁盘的原始访问(不要引用我的话)

于 2010-01-21T11:52:12.053 回答
1

Java 只能访问文件。Unix 有“原始设备”的概念,即 /dev 目录中的文件,所以你想要的在那里是可能的。但不是在 Windows 上,因为它没有原始高清数据的这种文件表示。

于 2010-01-21T10:23:23.163 回答
0

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

在 Windows 中,我认为您需要通过 JNI(Java 本机接口)读取/写入磁盘扇区。调用一些 C 库与操​​作系统对话。

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

https://metacpan.org/pod/Win32API::文件

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

于 2010-01-21T10:19:26.720 回答