Ich habe versucht, eine Datei mithilfe von FileInputStream in ein Array einzulesen, und das Einlesen einer ~ 800-KB-Datei in den Speicher dauerte ca. 3 Sekunden. Ich habe dann den gleichen Code ausprobiert, außer dass der FileInputStream in einen BufferedInputStream eingewickelt war und es ungefähr 76 Millisekunden dauerte. Warum wird das Lesen einer Datei byteweise mit einem BufferedInputStream so viel schneller durchgeführt, obwohl ich sie immer noch byteweise lese? Hier ist der Code (der Rest des Codes ist völlig irrelevant). Beachten Sie, dass dies der "schnelle" Code ist. Sie können den BufferedInputStream einfach entfernen, wenn Sie den "langsamen" Code möchten:
InputStream is = null;
try {
is = new BufferedInputStream(new FileInputStream(file));
int[] fileArr = new int[(int) file.length()];
for (int i = 0, temp = 0; (temp = is.read()) != -1; i++) {
fileArr[i] = temp;
}
BufferedInputStream ist über 30-mal schneller. Weit mehr als das. Warum ist das so und ist es möglich, diesen Code effizienter zu gestalten (ohne externe Bibliotheken zu verwenden)?
quelle
FileInputStream
derread(byte[], int, int)
Methode mit abyte[>8192]
keineBufferedInputStream
Umhüllung benötigen würden .read()
Byte für Byte verwendet und wann wird einread(byte[])
Array von Bytes verwendet ? Da ich denke, Array zu lesen ist immer besser. Dann können Sie mir ein Beispiel geben, woread()
Byte für Byte ODERread(byte[])
Array von Byte verwendet werden soll. ODERBufferedInputStream
.?read()
.BufferedInputStream
ist schneller, wenn Ihr Code jedes Mal weniger Bytes (nicht unbedingt nur ein Byte) als die Puffergröße lesen muss.BufferedInputStream
verhält sich optimistisch und liest mehr als nötig, sodass bei Ihrer Rückkehr bereits die nächste Charge vorhanden ist.Ein BufferedInputStream, der um einen FileInputStream gewickelt ist, fordert Daten vom FileInputStream in großen Blöcken an (standardmäßig etwa 512 Byte, glaube ich). Wenn Sie also nacheinander 1000 Zeichen lesen, muss der FileInputStream nur zweimal auf die Festplatte übertragen werden . Das wird viel schneller gehen!
quelle
Dies liegt an den Kosten für den Festplattenzugriff. Nehmen wir an, Sie haben eine Datei mit einer Größe von 8 KB. Zum Lesen dieser Datei ohne BufferedInputStream wird eine 8 * 1024-fache Zugriffsdiskette benötigt.
Zu diesem Zeitpunkt kommt BufferedStream in die Szene und fungiert als Vermittler zwischen FileInputStream und der zu lesenden Datei.
In einem Schuss werden standardmäßig 8 KB Bytes gespeichert, und FileInputStream liest dann Bytes von diesem mittleren Mann. Dies verkürzt die Betriebszeit.
private void exercise1WithBufferedStream() { long start= System.currentTimeMillis(); try (FileInputStream myFile = new FileInputStream("anyFile.txt")) { BufferedInputStream bufferedInputStream = new BufferedInputStream(myFile); boolean eof = false; while (!eof) { int inByteValue = bufferedInputStream.read(); if (inByteValue == -1) eof = true; } } catch (IOException e) { System.out.println("Could not read the stream..."); e.printStackTrace(); } System.out.println("time passed with buffered:" + (System.currentTimeMillis()-start)); } private void exercise1() { long start= System.currentTimeMillis(); try (FileInputStream myFile = new FileInputStream("anyFile.txt")) { boolean eof = false; while (!eof) { int inByteValue = myFile.read(); if (inByteValue == -1) eof = true; } } catch (IOException e) { System.out.println("Could not read the stream..."); e.printStackTrace(); } System.out.println("time passed without buffered:" + (System.currentTimeMillis()-start)); }
quelle