Как получить доступ к определенным необработанным данным на диске из java
Я пытаюсь использовать следующий код для доступа к одному байту со смещением 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 ответов
RandomAccessFile не предназначен для открытия каталогов для управления записями, вам нужно создавать или удалять файлы. "Acceso denegado", вероятно, означает отказ в доступе. Для этого в любом случае вам нужен JNI.
EDIT: то, что вы пытаетесь сделать, действительно сложно, нет общего способа сделать это. Вы можете получить доступ к жесткому диску по секторам, но тогда вам придется интерпретировать его структуру, которая,очевидно,зависит от файловой системы, FAT, NTFS, HPFS и т. д.
Я сам искал возможность доступа к необработанным данным из физического диска. И теперь, когда у меня это получилось, я просто хочу рассказать вам, как. Вы можете получить доступ к данным raw-диска непосредственно из java ... просто запустите следующий код с правами администратора:
File diskRoot = new File ("\\.\PhysicalDrive0");
RandomAccessFile diskAccess = new RandomAccessFile (diskRoot, "r");
byte[] content = new byte[1024];
diskAccess.readFully (content);
таким образом, вы получите первый КБ вашего первого физического диска в системе. Для доступа к логическим дискам - как упоминалось выше-просто замените "PhysicalDrive0" на букву диска, например Д:
да ... Я пробовал с Java 1.7 на системе Win 7 ...
просто взгляните на именование физических дисков в http://support.microsoft.com/kb/100027/en-us
если вы заинтересованы в писать на необработанный том под 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();
конечно, вы должны убедиться, что устройство для записи и недоступен/заблокирован системой. Также убедитесь, что ваше приложение работает с необходимыми правами (привилегиями).
Btw: Использование new RandomAccessFile(drive, "rw")
не работает, потому что Java не открывает дескриптор файла в режиме, совместимом с raw-устройствами (исключение java.io.FileNotFoundException (The parameter is incorrect)
). Но чтение отлично работает и с RandomAccessFile
.
под Linux вы можете попробовать открыть /dev/<device>
, например,/dev/hda
или /dev/sdb2
. Это даст вам доступ к необработанному диску (или только к разделу), но требует, чтобы у вас были соответствующие права-"нормальный" пользователь их не имеет.
Java может получить доступ только к файлам. Unix имеет концепцию "raw-устройств" как файлов в каталоге /dev, поэтому то, что вы хотите, возможно там. Но не в windows, потому что он не имеет такого представления файлов необработанных данных HD.
в windows вам нужно получить доступ к идентификатору raw-устройства в виде файла. Он должен работать, если вы передаете в файле "\\.\c:", вы используете имя UNC устройства \.\с.\( : значит эта машина).
для Vista и позже я не думаю, что она будет работать корректно, так как существуют механизмы для предотвращения прямого доступа к диску для чего-либо кроме драйверов (не цитируйте меня на этом)
@hunsricker : обратите внимание, что доступ к raw-устройствам требует некоторых привилегий (зависит от диска : съемный или нет / зависит от файловой системы для WinXP : iso9660 разрешен, FAT нет).
обратите внимание также, что размер чтения имеет значение (в зависимости от ОС) : В файловой системе iso9660 чтение (1024 байта) работает на XP, Но не выполняется на семи. На семи похоже, что чтения должны быть выровнены по блоку: чтение (2048 байт) работает.
в Unix, вы можете читать/писать из /dev
файлы. (Я не уверен)
в Windows, я думаю, вам нужно читать / записывать сектора диска через JNI (Java Native Interface). Вызывает некоторую библиотеку C, чтобы поговорить с ОС.
update: в библиотеке C вам может потребоваться использовать Win32API для получения дескриптора файла, например CreateFile(..)
функция.