Zugriff auf Windows-Festplatten direkt mit Java NIO

8

Ich verwende eine Bibliothek, die Java NIO verwendet, um Dateien direkt in den Speicher zu mappen, aber ich habe Probleme beim direkten Lesen von Datenträgern.

I kann die Datenträger direkt mit FileInputStream mit UNC lesen, z. B.

%Vor%

Allerdings kann ich nicht auf NIO erweitern:

%Vor%

Der Stacktrace (bis zur Ursache) ist:

%Vor%

Ich habe keine Lösung gefunden, obwohl ich etwas auf So greifen Sie von Java auf bestimmte Rohdaten auf der Festplatte zu . Die Antwort von Daniel Alder, die die Verwendung von GLOBALROOT vorschlägt, scheint relevant zu sein, da die Antwort FileChannel in der Antwort verwendet, aber ich kann das Laufwerk nicht mit diesem Muster finden. Gibt es eine Möglichkeit, alle Geräte unter GLOBALROOT oder ähnlichem aufzulisten?

Im Moment versuche ich, die Verwendung von NIO durch gerade InputStream s zu ersetzen, aber ich möchte das vermeiden, wenn ich kann. Erstens wurde NIO aus einem bestimmten Grund verwendet und zweitens durchläuft es eine Menge Code und erfordert viel Arbeit. Schließlich würde ich gerne wissen, wie man etwas wie Daniels Lösung implementiert, damit ich in Zukunft auf Geräte schreiben oder NIO verwenden kann.

Also zusammenfassend: Wie kann ich direkt mit Java NIO auf Laufwerke zugreifen (nicht InputStream s) und / oder gibt es eine Möglichkeit, alle Geräte aufzulisten, auf die über GLOBALROOT zugegriffen werden kann, damit ich Daniel Alsers Lösung verwenden kann?

>

Zusammenfassung der Antworten: Ich habe die letzten Änderungen (unten) beibehalten, um Verwirrung zu vermeiden. Mit Hilfe von EJP und Apangin denke ich, dass ich eine praktikable Lösung habe. Etwas wie

%Vor%

Dies funktioniert, solange der Parameter posn ein Vielfaches der Sektorgröße ist (in diesem Fall auf 512 gesetzt). Beachten Sie, dass dies auch mit dem Channels.newChannel (FileInputStream) funktioniert, der in diesem Fall immer einen SeekableByteStream zurückgibt und es erscheint , dass es sicher in einen umgewandelt werden kann.

Aus dem schnellen und schmutzigen Testen erscheint , dass diese Methoden wirklich suchen und nicht einfach überspringen. Ich habe zu Beginn meiner Fahrt nach tausend Orten gesucht und sie gelesen. Ich habe das gleiche getan, aber einen Offset von der Hälfte der Festplattengröße hinzugefügt (um die Rückseite der Festplatte zu suchen). Ich fand:

  • Beide Methoden haben fast die gleiche Zeit gebraucht.
  • Beim Suchen am Anfang oder am Ende der Festplatte hat nicht Auswirkungen auf die Zeit.
  • Reduzierung der Reichweite der Adressen did reduziert die Zeit.
  • Das Sortieren der Adressen did reduziert die Zeit, aber nicht viel.

Dies deutet darauf hin, dass dies wirklich anstrebt und nicht nur das Lesen und Überspringen (wie ein Strom dazu tendiert). Die Geschwindigkeit ist in dieser Phase immer noch schrecklich und meine Festplatte klingt wie eine Waschmaschine, aber der Code wurde für einen schnellen Test entwickelt und muss noch schön gemacht werden. Es kann immer noch gut funktionieren.

Danke an EJP und Apangin für die Hilfe. Lesen Sie mehr in ihren jeweiligen Antworten.

Bearbeiten: Ich habe meinen Code auf einem Windows 7-Rechner ausgeführt (ich hatte ursprünglich keinen), und ich bekomme eine etwas andere Ausnahme (siehe unten). Dies wurde mit Admin-Rechten ausgeführt, und das erste Stück Code funktioniert immer noch unter den gleichen Bedingungen.

%Vor%

Bearbeiten 2: Als Antwort auf EJP habe ich versucht:

%Vor%

Wenn ich das versuche, bekomme ich folgende Ausgabe:

  

Kanal erstellt
     Oh, stören: java.io.IOException: Der Parameter ist falsch

So scheint es, dass ich einen FileChannel oder ReadableByteChannel erstellen kann, aber ich kann es nicht verwenden; das heißt, der Fehler wird einfach zurückgestellt.

    
timbo 04.03.2014, 02:56
quelle

3 Antworten

3

Beim Zugriff auf ein physikalisches Laufwerk ohne Pufferung können Sie nur vollständige Sektoren lesen. Dies bedeutet, dass bei einer Sektorgröße von 512 Byte nur ein Vielfaches von 512 Byte gelesen werden kann. Ändern Sie Ihre Pufferlänge auf 512 oder 4096 (unabhängig von der Sektorgröße) und FileChannel funktioniert einwandfrei:

%Vor%

Siehe Anforderungen für Ausrichtung und Dateizugriff .

Ihr ursprünglicher FileInputStream Code funktioniert offensichtlich wegen BufferedInputStream , das die Standardpuffergröße von 8192 hat. Nehmen Sie es weg - und der Code wird mit derselben Ausnahme fehlschlagen.

    
apangin 08.11.2014, 17:06
quelle
1

Bei Verwendung von NIO muss sich der ursprüngliche Code nur geringfügig ändern.

%Vor%

Ist in Ordnung, bearbeitbarer Code, aber ich bekomme einen Zugriff verweigert Fehler sowohl in Ihrer Version und mir.

    
Steve K 06.11.2014 04:48
quelle
1

Führen Sie dies als Administrator aus. Es funktioniert wirklich, da es nur ein dünner Wrapper über java.io:

ist %Vor%

BEARBEITEN Wenn Sie einen wahlfreien Zugriff benötigen, bleiben Sie bei RandomAccessFile hängen. Es gibt keine Zuordnung von diesem über Channels . Aber die obige Lösung ist sowieso nicht NIO, nur eine Java NIO-Schicht über FileInput/OutputStream .

    
EJP 06.11.2014 04:00
quelle

Tags und Links