【问题标题】:How to access specific raw data on disk from java如何从java访问磁盘上的特定原始数据
【发布时间】:2011-01-07 16:13:24
【问题描述】:

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

【问题讨论】:

    标签: java drive


    【解决方案1】:

    在Linux下你可以尝试打开/dev/&lt;device&gt;,例如/dev/hda,或/dev/sdb2。这将允许您访问原始磁盘(或仅分区),但需要您拥有适当的权限——不过,“普通”用户没有这些权限。

    【讨论】:

    • 这就是我想要模仿的。 f=open("/dev/sda",O_RDONLY);
    【解决方案2】:

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

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

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

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

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

    【讨论】:

    • 好吧,假设我将创建一个JNI库,我不知道'open' C函数中传递的第一个参数是什么: f=open("C:",O_RDONLY); ???
    【解决方案3】:

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

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

    【讨论】:

    • 尝试通过 JNI,但没有运气: fp = fopen("c:", "r"))
    • 看这里如何读取磁盘上的扇区:codeguru.com/cpp/w-p/system/misc/article.php/c5765
    • 非常感谢!!这解决了我的问题: fp = fopen("\\\\.\\C:", "r")) 现在我只需要创建一个 JNI 库,但奇怪的是还没有人创建它。
    【解决方案4】:

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

    【讨论】:

    • 您现在可能知道,Windows 也有自己的方法来访问原始设备,使用称为“UNC 文件”或“UNC 路径”的东西。它们相当于访问远程资源的网络路径,例如\\resource,但必须使用\\.\resource作为资源引用自己的机器,例如PhysicalDrive0
    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

      • 谢谢。有用。我已经使用 BufferedInputStream 做了同样的事情。只需使用管理权限打开您的程序或 CLI。我也使用了 File 对象,但是 exists() 方法不会返回肯定的结果,所以要小心。
      • 如何授予管理权限。请回复
      【解决方案7】:

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

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

      【讨论】:

        【解决方案8】:

        如果您对在 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 也可以正常阅读。

        【讨论】:

        • 很好的答案;感谢您使用 NIO API 专门解决 WRITE。
        猜你喜欢
        • 1970-01-01
        • 2017-05-11
        • 2013-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-07
        • 2011-11-28
        • 2014-10-24
        相关资源
        最近更新 更多