files - Cómo acceder a datos en bruto específicos en el disco desde Java
rest api drive (8)
Estoy intentando usar el siguiente código para acceder a un byte con un desplazamiento de 50 bytes en un disco en bruto.
randomAccessFile = new RandomAccessFile("C:", "r");
randomAccessFile.seek(50);
byte[] buffer = new byte[1];
randomAccessFile.read(buffer);
Pero todo lo que consigo es el siguiente error:
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)
¿Hay alguna forma de acceder a un byte preciso en un disco desde Java?
@hunsricker: tenga en cuenta que acceder a dispositivos sin formato requiere algunos privilegios (depende de la unidad: removible o no / depende del sistema de archivos para WinXP: iso9660 está permitido, FAT no).
Tenga en cuenta también que el tamaño de la lectura sí importa (según el sistema operativo): en un sistema de archivos iso9660, la lectura (1024 bytes) funciona en XP, pero falla en Siete. En Siete parece que las lecturas deben estar alineadas por bloques: funciona la lectura (2048 bytes).
Bajo Linux, puede intentar abrir /dev/<device>
, por ejemplo, /dev/hda
o /dev/sdb2
. Esto le dará acceso a un disco sin formato (o solo a una partición), pero requiere que tenga los derechos adecuados; sin embargo, un usuario "normal" no los tiene.
En Unix, puedes leer / escribir desde archivos /dev
. (No estoy seguro)
En Windows, creo que necesita leer / escribir sectores de disco a través de JNI (Java Native Interface). Llama a alguna biblioteca de C para hablar con el sistema operativo.
actualización: en la biblioteca C, es posible que necesite usar Win32API para obtener el identificador de archivo, por ejemplo, la función CreateFile(..)
.
En Windows, debe acceder al identificador de dispositivo sin formato como un archivo. Debería funcionar si pasa el archivo "//. / C:", está usando el nombre UNC del dispositivo /. / C: (/. Significa esta máquina).
Para Vista y más adelante, no creo que funcione correctamente, ya que existen mecanismos para evitar el acceso directo al disco para cualquier otra cosa que no sean controladores de dispositivos (no me cites en eso)
Estaba buscando por mi mismo la posibilidad de acceder a datos en bruto desde un disco físico. Y ahora, como lo hice funcionar, solo quiero decirles cómo. Puede acceder a los datos del disco sin procesar directamente desde java ... simplemente ejecute el siguiente código con privilegios de administrador:
File diskRoot = new File ("////.//PhysicalDrive0");
RandomAccessFile diskAccess = new RandomAccessFile (diskRoot, "r");
byte[] content = new byte[1024];
diskAccess.readFully (content);
Así obtendrá el primer kB de su primer disco físico en el sistema. Para acceder a las unidades lógicas, como se mencionó anteriormente, simplemente reemplace ''PhysicalDrive0'' con la letra de la unidad, por ejemplo, ''D:''
oh sí ... intenté con Java 1.7 en un sistema Win 7 ...
Simplemente eche un vistazo a la denominación de unidades físicas en http://support.microsoft.com/kb/100027/en-us
Java solo puede acceder a los archivos. Unix tiene el concepto de "dispositivos en bruto" como archivos en el directorio / dev, por lo que lo que desea es posible allí. Pero no en Windows, porque no tiene tal representación de archivo de los datos HD sin procesar.
RandomAccessFile no está diseñado para abrir directorios para manipular entradas, es necesario crear o eliminar archivos. "Acceso denegado" probablemente significa acceso denegado. Para hacer esto de todos modos necesitas JNI.
EDIT: Lo que está tratando de hacer, es realmente complicado, no hay una forma común de hacerlo. Puede acceder al sector del disco duro por sector, pero luego tendría que interpretar su estructura, que obviamente depende del sistema de archivos, FAT, NTFS, HPFS, etc.
Si está interesado en escribir en un volumen sin procesar en Windows, intente esto (necesita 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();
Por supuesto, debe asegurarse de que el dispositivo pueda escribirse y que el sistema no pueda acceder o bloquearlo. También asegúrese de que su aplicación se ejecute con los privilegios necesarios (privilegios elevados).
Por cierto: el uso de un new RandomAccessFile(drive, "rw")
no parece funcionar porque Java no abre el identificador de archivo en un modo que es compatible con dispositivos en bruto (la excepción es java.io.FileNotFoundException (The parameter is incorrect)
). Pero la lectura funciona bien también con RandomAccessFile
.