4 Stimmen

Wie kann man große Dateien in Java in Teilen lesen, ohne dass sie blockiert werden?

Angenommen, Sie haben eine Datei, die größer ist als Ihr Speicherplatz. Sie möchten die Dateien lesen n Bytes im Wechsel y dabei nicht blockiert werden

  • einen Block lesen
  • an einen Thread übergeben
  • einen anderen Block lesen
  • an einen Thread übergeben

Ich habe verschiedene Dinge mit unterschiedlichem Erfolg ausprobiert, aber die Blockierung scheint immer das Problem zu sein.

Bitte geben Sie ein Beispiel für eine blockierungsfreie Methode um Zugang zu erhalten zu, sagen wir byte[]

6voto

parsifal Punkte 131

Das können Sie nicht.

Sie werden immer blockieren, während Sie darauf warten, dass die Festplatte Ihnen Daten liefert. Wenn Sie mit jedem Datenpaket viel Arbeit zu erledigen haben, kann die Verwendung eines zweiten Threads hilfreich sein: Dieser Thread kann CPU-intensive Arbeit an den Daten durchführen, während der erste Thread blockiert ist und auf den Abschluss des nächsten Lesevorgangs wartet.

Aber das klingt nicht nach Ihrer Situation.

Am besten ist es, Daten in möglichst großen Blöcken zu lesen (z. B. 1 MB oder mehr). Dadurch wird die im Kernel blockierte Zeit minimiert und die Wartezeit auf die Festplatte verkürzt (wenn die zu lesenden Blöcke zusammenhängend sind).


Hier ist der Codez

ExecutorService exec = Executors.newFixedThreadPool(1);

// use RandomAccessFile because it supports readFully()
RandomAccessFile in = new RandomAccessFile("myfile.dat", "r");
in.seek(0L);

while (in.getFilePointer() < in.length())
{
    int readSize = (int)Math.min(1000000, in.length() - in.getFilePointer());
    final byte[] data = new byte[readSize];
    in.readFully(data);
    exec.execute(new Runnable() 
    {
        public void run() 
        {
            // do something with data
        }
    });
}

1voto

Cody S Punkte 4644

Es klingt wie Sie sind auf der Suche nach Streams, Pufferung, oder eine Kombination aus den beiden (BufferedInputStream jemand?).

Sehen Sie sich das an: http://docs.oracle.com/javase/tutorial/essential/io/buffers.html

Dies ist die Standardmethode, um mit sehr großen Dateien umzugehen. Ich entschuldige mich, wenn dies nicht das ist, wonach Sie gesucht haben, aber ich hoffe, es hilft Ihnen trotzdem, die Dinge in Gang zu bringen.

Viel Glück!

0voto

Raedwald Punkte 43209

Wenn Sie ein Programm haben, das E/A- und CPU-Berechnungen durchführt, ist ein Blockieren unvermeidlich (irgendwo in Ihrem Programm), wenn die CPU-Zeit, die für die Verarbeitung eines Bytes benötigt wird, im Durchschnitt geringer ist als die Zeit zum Lesen eines Bytes.

Wenn Sie versuchen, eine Datei zu lesen, und dies einen Festplattenzugriff erfordert, kommen die Daten möglicherweise erst nach 10 ms an. Eine 2-GHz-CPU könnte in dieser Zeit 20 Mio. Taktzyklen an Arbeit erledigt haben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X