How to access specific raw data on disk from java
I'm trying to use the following code to access one byte with offset of 50 bytes in a raw disk.
randomAccessFile = new RandomAccessFile("C:", "r");
randomAccessFile.seek(50);
byte[] buffer = new byte[1];
randomAccessFile.read(buffer);
But all what I get is the following error:
java.io.FileNo开发者_JAVA百科tFoundException: 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)
Is there any way to access a precise byte in a drive from java?
I was looking by myself for a possibility to access raw data form a physical drive. And now as I got it to work, I just want to tell you how. You can access raw disk data directly from within java ... just run the following code with administrator priviliges:
File diskRoot = new File ("\\\\.\\PhysicalDrive0");
RandomAccessFile diskAccess = new RandomAccessFile (diskRoot, "r");
byte[] content = new byte[1024];
diskAccess.readFully (content);
So you will get the first kB of your first physical drive on the system. To access logical drives - as mentioned above - just replace 'PhysicalDrive0' with the drive letter e.g. 'D:'
oh yes ... I tried with Java 1.7 on a Win 7 system ...
Just have a look at the naming of physical drives at http://support.microsoft.com/kb/100027/en-us
If you are interested in writing to a raw volume under Windows, try this (needs 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();
Of course, you have to make sure the device is writable and not accessed/locked by the system. Also make sure your application runs with the necessary privileges (elevated privileges).
Btw: Using new RandomAccessFile(drive, "rw")
doesn't seem to work because Java doesn't open the file handle in a mode which is compatible to raw devices (exception is java.io.FileNotFoundException (The parameter is incorrect)
). But reading works fine also with RandomAccessFile
.
RandomAccessFile is not meant to open directories to manipulate entries, you need to create or remove files. "Acceso denegado" probably mean access denied. To do this anyway you need JNI.
EDIT: What you are trying to do, is really complicated, there is no common way to do that. You can access the harddisc sector by sector, but then you would have to interpret it's structure, which obviously depends on the file system, FAT,NTFS,HPFS etc.
Under Linux you can try to open /dev/<device>
, e.g. /dev/hda
, or /dev/sdb2
. This will give you access to a raw disk (or a partition only) but requires that you have appropriate rights—a “normal” user does not have them, though.
Java can only access files. Unix has the concept of "raw devices" as files in the /dev directory, so what you want is possible there. But not on windows, because it has no such file representation of the raw HD data.
In windows you need to access the raw device identifier as a file. It should work if you pass in the file "\\.\c:", you are using the device UNC name \.\c: (\. means this machine).
For Vista and later I don't think it will work correctly as there are mechanisms in place to prevent raw access to the disk for anything other than device drivers (don't quote me on that)
@hunsricker : note that accessing raw devices require some privileges (depends on drive : removable or not / depends on file system for WinXP : iso9660 is allowed, FAT is not).
Note also that size of read does matter (depending on OS) : On an iso9660 filesystem, read(1024 bytes) works on XP but fails on Seven. On Seven it look like the reads must be block aligned : read(2048 bytes) works.
In unix, you may read/write from /dev
files. (I'm not sure)
In Windows, I think you need to read/write disk sectors via JNI(Java Native Interface). Calls some C library to talk to the OS.
update: In C library, you may need to use Win32API to get the file handle for example CreateFile(..)
function.
https://metacpan.org/pod/Win32API::File
http://jan.newmarch.name/ssw/files/win32.html
精彩评论