2010-01-21 34 views
16

Tôi đang cố gắng sử dụng mã sau để truy cập một byte có độ lệch là 50 byte trong đĩa thô.Cách truy cập dữ liệu thô cụ thể trên đĩa từ java

randomAccessFile = new RandomAccessFile("C:", "r"); 
randomAccessFile.seek(50); 
byte[] buffer = new byte[1]; 
randomAccessFile.read(buffer); 

Nhưng tất cả những gì tôi nhận được là các lỗi sau:

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) 

Có cách nào để truy cập vào một byte chính xác trong một ổ đĩa từ java?

+0

đã cập nhật câu trả lời của tôi – stacker

Trả lời

4

RandomAccessFile không có nghĩa là để mở thư mục để thao tác mục, bạn cần phải tạo ra hoặc xoá các file. "Acceso denegado" có thể có nghĩa là truy cập bị từ chối. Để thực hiện việc này, bạn cần JNI.

EDIT: Những gì bạn đang cố gắng làm, thực sự phức tạp, không có cách nào phổ biến để làm điều đó. Bạn có thể truy cập khu vực ổ cứng theo ngành, nhưng sau đó bạn sẽ phải giải thích cấu trúc của nó, rõ ràng là phụ thuộc vào hệ thống tệp, FAT, NTFS, HPFS, v.v.

+0

cố gắng thông qua JNI, nhưng không có may mắn: fp = fopen ("c:", "r")) <- không có lỗi fseek (fp, i, SEEK_SET) <- không có lỗi getc (fp) <- luôn luôn trả về cùng một dữ liệu bất kể tham số i cho fseek là – user178973

+0

Xem tại đây cách đọc các sector trên đĩa: http://www.codeguru.com/cpp/wp/system/misc/article.php/c5765/ – stacker

+0

Cảm ơn rất nhiều !! giải quyết vấn đề của tôi: fp = fopen ("\\\. \\ C:", "r")) Bây giờ tôi chỉ phải tạo một thư viện JNI, nhưng đó là curios mà chưa ai tạo ra nó. – user178973

3

Trong Linux, bạn có thể thử mở /dev/<device>, ví dụ: /dev/hda hoặc /dev/sdb2. Điều này sẽ cho phép bạn truy cập vào một đĩa thô (hoặc một phân vùng duy nhất) nhưng yêu cầu bạn có quyền thích hợp - một người dùng “bình thường” không có chúng.

+0

Đó là những gì tôi đang cố gắng mô phỏng. f = open ("/ dev/sda", O_RDONLY); – user178973

1

Trong unix, bạn có thể đọc/ghi từ /dev tệp. (Tôi không chắc chắn)

Trong Windows, tôi nghĩ bạn cần đọc/ghi các sector đĩa thông qua JNI (Giao diện bản địa Java). Gọi một số thư viện C để nói chuyện với hệ điều hành.

cập nhật: Trong thư viện C, bạn có thể cần sử dụng Win32API để xử lý tệp chẳng hạn như hàm CreateFile(..).

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

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

+0

Vâng, giả sử tôi sẽ tạo ra một thư viện JNI, tôi không biết tham số đầu tiên để vượt qua trong chức năng 'mở' C là gì: f = open ("C:", O_RDONLY); ??? – user178973

1

Java chỉ có thể truy cập tệp. Unix có khái niệm về "các thiết bị thô" như các tệp trong thư mục/dev, vì vậy những gì bạn muốn là có thể có. Nhưng không phải trên cửa sổ, bởi vì nó không có đại diện tập tin như vậy của dữ liệu HD thô.

+0

Như bạn đã biết, Windows cũng có các phương pháp riêng để truy cập các thiết bị thô, sử dụng một thứ gọi là "UNC files" hoặc "UNC paths". Chúng tương đương với đường dẫn mạng để truy cập tài nguyên từ xa, ví dụ: '\\ resource', nhưng bạn phải tham chiếu đến máy tính của riêng bạn bằng cách sử dụng' \\. \ resource', là tài nguyên, ví dụ 'PhysicalDrive0'. – Azurlake

1

Trong cửa sổ, bạn cần truy cập số nhận dạng thiết bị thô dưới dạng tệp. Nó sẽ hoạt động nếu bạn chuyển vào tập tin "\\. \ C:", bạn đang sử dụng tên thiết bị UNC \. \ C: (\. Có nghĩa là máy này).

Đối với Vista và sau đó tôi không nghĩ rằng nó sẽ làm việc một cách chính xác như có cơ chế tại chỗ để ngăn chặn truy cập liệu vào đĩa cho bất cứ điều gì khác hơn là trình điều khiển thiết bị (không báo cho tôi về điều đó)

16

tôi đã tự tìm kiếm khả năng truy cập dữ liệu thô tạo thành một ổ đĩa vật lý. Và bây giờ khi tôi làm việc, tôi chỉ muốn nói cho bạn biết làm thế nào. Bạn có thể truy cập dữ liệu đĩa thô trực tiếp từ bên trong java ... chỉ cần chạy mã sau đây với quyền quản trị viên:

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

Vì vậy, bạn sẽ nhận được kB đầu tiên của ổ đĩa vật lý đầu tiên trên hệ thống. Để truy cập các ổ đĩa logic - như đã đề cập ở trên - chỉ cần thay thế 'PhysicalDrive0' bằng ký tự ổ đĩa, ví dụ: 'D:'

oh có ... Tôi đã thử với Java 1.7 trên hệ thống Win 7 ...

Chỉ cần có một cái nhìn tại việc đặt tên của ổ đĩa vật lý tại http://support.microsoft.com/kb/100027/en-us

+0

Cảm ơn vì điều này. Nó hoạt động. Tôi đã thực hiện tương tự bằng cách sử dụng BufferedInputStream. Chỉ cần mở chương trình hoặc CLI của bạn với quyền quản trị. Tôi cũng đã sử dụng đối tượng File, tuy nhiên phương thức tồn tại() sẽ không trả về một kết quả tích cực nào nên hãy cẩn thận về điều đó. – mikato

+0

Cách cấp đặc quyền quản trị.hãy trả lời –

1

@hunsricker: lưu ý rằng việc truy cập các thiết bị thô yêu cầu một số đặc quyền (tùy thuộc vào ổ đĩa: di động hay không/phụ thuộc vào hệ thống tập tin cho WinXP: iso9660 được phép , FAT không phải là).

Lưu ý rằng kích thước của đọc không quan trọng (tùy thuộc vào hệ điều hành): Trên hệ thống tệp iso9660, đọc (1024 byte) hoạt động trên XP nhưng không thành công trên Seven. Trên Seven nó trông giống như các lần đọc phải được khối liên kết: đọc (2048 byte) hoạt động.

10

Nếu bạn quan tâm đến việc viết vào một ổ đĩa thô trong Windows, hãy thử điều này (cần 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(); 

Tất nhiên, bạn phải đảm bảo thiết bị có thể ghi và không được truy cập/khóa bởi hệ thống. Ngoài ra hãy chắc chắn rằng ứng dụng của bạn chạy với các đặc quyền cần thiết (đặc quyền nâng cao).

Btw: Sử dụng new RandomAccessFile(drive, "rw") dường như không hoạt động vì Java không mở xử lý tệp ở chế độ tương thích với thiết bị thô (ngoại lệ là java.io.FileNotFoundException (The parameter is incorrect)). Nhưng đọc cũng hoạt động tốt với RandomAccessFile.

+0

Câu trả lời hay; đánh giá cao việc bạn giải quyết VIẾT cụ thể bằng cách sử dụng API NIO. –

Các vấn đề liên quan