Как получить доступ к конкретным необработанным данным на диске из Java - PullRequest
17 голосов
/ 21 января 2010

Я пытаюсь использовать следующий код для доступа к одному байту со смещением 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 ]

16 голосов
/ 23 декабря 2011

Я искал возможность доступа к необработанным данным с физического диска. И теперь, когда я заставил его работать, я просто хочу рассказать вам, как. Вы можете получить доступ к необработанным данным на диске непосредственно из Java ... просто запустите следующий код с привилегиями администратора:

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

Таким образом, вы получите первый килобайт вашего первого физического диска в системе. Чтобы получить доступ к логическим дискам, как указано выше, просто замените PhysicalDrive0 на букву диска, например 'D:'

о да ... я пытался с Java 1.7 в системе Win 7 ...

Просто посмотрите на имена физических дисков на http://support.microsoft.com/kb/100027/en-us

10 голосов
/ 01 ноября 2013

Если вас интересует запись на сырой том под 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.

4 голосов
/ 21 января 2010

RandomAccessFile не предназначен для открытия каталогов для манипулирования записями, вам нужно создавать или удалять файлы. «Acceso denegado», вероятно, означает, что доступ запрещен. В любом случае, вам нужен JNI.

РЕДАКТИРОВАТЬ: То, что вы пытаетесь сделать, действительно сложно, нет общего способа сделать это. Вы можете получить доступ к сектору жесткого диска по секторам, но тогда вам придется интерпретировать его структуру, которая, очевидно, зависит от файловой системы, FAT, NTFS, HPFS и т. Д.

3 голосов
/ 21 января 2010

В Linux вы можете попробовать открыть /dev/<device>, например. /dev/hda или /dev/sdb2. Это даст вам доступ к сырому диску (или только к разделу), но требует, чтобы у вас были соответствующие права, хотя у «обычного» пользователя их нет.

1 голос
/ 22 февраля 2012

@ hunsricker: обратите внимание, что для доступа к необработанным устройствам требуются некоторые права (зависит от диска: съемный или нет / зависит от файловой системы для WinXP: iso9660 разрешен, FAT - нет).

Обратите внимание, что размер чтения имеет значение (в зависимости от ОС): В файловой системе iso9660 read (1024 bytes) работает на XP, но не работает на Seven. На Семи это выглядит так, как будто чтения должны быть выровнены по блокам: чтение (2048 байт) работает.

1 голос
/ 21 января 2010

В Windows вам необходимо получить доступ к необработанному идентификатору устройства в виде файла. Это должно работать, если вы передаете файл "\\. \ C:", вы используете UNC-имя устройства \. \ C: (\. Означает этот компьютер).

Для Vista и более поздних версий я не думаю, что она будет работать правильно, поскольку существуют механизмы, предотвращающие необработанный доступ к диску для чего-либо, кроме драйверов устройств (не указывайте это)

1 голос
/ 21 января 2010

Java может обращаться только к файлам. Unix имеет концепцию «сырых устройств» как файлов в каталоге / dev, так что то, что вы хотите, там возможно Но не в Windows, потому что у него нет такого представления файлов необработанных данных HD.

1 голос
/ 21 января 2010

В 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

...