2016-09-08 5 views
2

So habe ich versucht, ein kleines Programm, das eine Datei in ein Byte-Array eingibt, dann wird dieses Byte-Array in hex, dann binär. Es wird dann mit den binären Werten spielen (ich habe nicht darüber nachgedacht, was ich tun soll, wenn ich zu diesem Zeitpunkt komme) und es dann als eine benutzerdefinierte Datei speichern.Java Große Dateien in Byte-Array lesen Chunk für Chunk

Ich studierte viel Internet-Code und ich kann eine Datei in ein Byte-Array und in Hex, aber das Problem ist, kann ich keine großen Dateien in Byte-Arrays (nicht genügend Arbeitsspeicher).

Dies ist der Code, der

public void rundis(Path pp) { 
    byte bb[] = null; 

    try { 
     bb = Files.readAllBytes(pp); //Files.toByteArray(pathhold); 
     System.out.println("byte array made"); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    if (bb.length != 0 || bb != null) { 
     System.out.println("byte array filled"); 
     //send to method to turn into hex 
    } else { 
     System.out.println("byte array NOT filled"); 
    } 

} 

Ich weiß, wie der Prozess sollte nicht ein Totalausfall ist, aber ich weiß nicht, wie das richtig zu codieren.

Der Prozess, wenn Sie interessiert sind:

  • Eingabedatei File
  • Lesen Sie den Brocken von Brocken der Datei in ein Byte-Array. Ex. Jeder Datensatz Byte-Array 600 Byte halten
  • dass chunk senden, um in einen Hexadezimalwert gedreht werden ->Integer.tohexstring
  • dass Hexadezimalwert chunk Senden in einen binären Wert gemacht werden ->Integer.toBinarystring
  • Mess herum mit der Binärwert
  • speichern, um benutzerdefinierte Datei Zeile für Zeile

Problem :: ich weiß nicht, wie man eine große Datei in einen Byte-Array chunk von Klumpen drehen verarbeitet werden. Jedwedes Hilfe wird geschätzt werden, danke für das Lesen :)

+0

Wie groß ist die Datei? –

+0

irgendwo um 7GB – h0lmesxx

+0

Betrachten Sie ['FileInputStream # lesen (byte [] b)'] (https://docs.oracle.com/javase/8/docs/api/java/io/FileInputStream.html#read-byte :EIN-). Dann können Sie angeben, wie viele Bytes gleichzeitig gelesen werden sollen. – 4castle

Antwort

5

ihre Eingabe mit Chunk ein Fileinputstream verwenden:

Path pp = FileSystems.getDefault().getPath("logs", "access.log"); 
    final int BUFFER_SIZE = 1024*1024; //this is actually bytes 

    FileInputStream fis = new FileInputStream(pp.toFile()); 
    byte[] buffer = new byte[BUFFER_SIZE]; 
    int read = 0; 
    while((read = fis.read(buffer)) > 0){ 
     // call your other methodes here... 
    } 

    fis.close(); 
+0

Danke für den helfenden Mann :) – h0lmesxx

1

Um eine Datei zu streamen, müssen Sie Schritt weg von Files.readAllBytes(). Es ist ein nettes Dienstprogramm für kleine Dateien, aber Sie haben nicht so viel für große Dateien bemerkt.

In Pseudo-Code wäre es etwa so aussehen:

while there are more bytes available 
    read some bytes 
    process those bytes 
    (write the result back to a file, if needed) 

In Java können Sie eine FileInputStream verwenden, um eine Datei byte by byte oder chunk by chunk zu lesen. Sagen wir, wir wollen unsere verarbeiteten Bytes zurückschreiben. Zuerst öffnen wir die Dateien:

FileInputStream is = new FileInputStream(new File("input.txt")); 
FileOutputStream os = new FileOutputStream(new File("output.txt")); 

Wir haben die FileOutputStream müssen unsere Ergebnisse schreiben zurück - wir wollen nicht nur unsere kostbare verarbeiteten Daten fallen, nicht wahr? Als nächstes müssen wir einen Puffer, der ein Stück von Bytes hält:

byte[] buf = new byte[4096]; 

Wie viele Bytes an Sie ist, dass ich ein bisschen wie Stücke von 4096 Bytes. Dann brauchen wir tatsächlich einige Bytes lesen

int read = is.read(buf); 

dies bis zu buf.length Bytes lesen und speichern sie in buf. Es gibt die gesamten gelesenen Bytes zurück.Dann verarbeiten wir die Bytes:

//Assuming the processing function looks like this: 
//byte[] process(byte[] data, int bytes); 
byte[] ret = process(buf, read); 

process() in obigem Beispiel ist die Verarbeitungsmethode. Es nimmt ein Byte-Array auf, die Anzahl der Bytes, die es verarbeiten soll, und gibt das Ergebnis als Byte-Array zurück.

Last, schreiben wir das Ergebnis zurück in eine Datei:

os.write(ret); 

Wir haben dies in einer Schleife ausgeführt, bis es kein Bytes links in der Datei ist, kann so eine Schleife für sie schreiben:

int read = 0; 
while((read = is.read(buf)) > 0) { 
    byte[] ret = process(buf, read); 
    os.write(ret); 
} 

und schließen schließlich die Ströme

is.close(); 
os.close(); 

und es das ist. Wir haben die Datei in 4096-Byte-Blöcken verarbeitet und das Ergebnis zurück in eine Datei geschrieben. Es liegt an Ihnen, was mit dem Ergebnis zu tun, Sie könnten es auch über TCP senden oder sogar fallen lassen, wenn es nicht benötigt wird, oder lesen von TCP anstelle einer Datei, die grundlegende Logik ist die gleiche.

Dies erfordert immer noch einige ordnungsgemäße Fehlerbehandlung, um fehlende Dateien oder falsche Berechtigungen zu umgehen, aber das liegt an Ihnen, das zu implementieren.


Eine Beispiel-Implementierung für die Prozessmethode:

//returns the hex-representation of the bytes 
public static byte[] process(byte[] bytes, int length) { 
    final char[] hexchars = "ABCDEF".toCharArray(); 
    char[] ret = new char[length * 2]; 
    for (int i = 0; i < length; ++i) { 
     int b = bytes[i] & 0xFF; 
     ret[i * 2] = hexchars[b >>> 4]; 
     ret[i * 2 + 1] = hexchars[b & 0x0F]; 
    } 
    return ret; 
} 
+0

Danke für die detaillierte Erklärung Mann :) aber können Sie ein wenig über den Teil erklären, der "Prozess (buf, lesen)" sagt. Was genau ist Prozess? – h0lmesxx

+0

Dies ist Ihre Verarbeitungsfunktion, die etwas mit den Bytes "tut". Ich habe eine Beispielimplementierung hinzugefügt, die die hexadezimale Darstellung der Bytes zurückgibt. – tkausl

+0

Das ist dumm, also hilfe auf eigene Gefahr :) Ich habe versucht, die Werte, die ich von Puffer-Array zu einem anderen Array bekam, es funktioniert nicht. Danke, dass du dir aus dem Weg geholt hast, um dem Menschen zu helfen :) ** Edit ** hilf mir nicht mit dem dummen Ding, das ich schon erwähnt habe, krank es herauszufinden – h0lmesxx