tutorials.de Buch-Aktion 05/2012
Like Tree2Danke
  • 1 Beitrag von Vereth
  • 1 Beitrag von Thomas Darimont
ERLEDIGT
NEIN
ANTWORTEN
8
ZUGRIFFE
1521
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    chocox chocox ist offline Mitglied
    Registriert seit
    Jul 2007
    Beiträge
    23
    Hallo zusammen,

    ich lese einen Datenstrom als Byte-Array ein. Dieses Byte Array wandle ich anschließend in Hex um. Und zwar so:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
    static String byteArrayToHexString(byte in[]) {
     
        byte ch = 0x00;
        int i = 0; 
        if (in == null || in.length <= 0)
            return null;
     
        String pseudo[] = {"0", "1", "2",
    "3", "4", "5", "6", "7", "8",
    "9", "A", "B", "C", "D", "E",
    "F"};
     
    StringBuffer out = new StringBuffer(in.length * 2);
     
        while (i < in.length) {
            ch = (byte) (in[i] & 0xF0);
            ch = (byte) (ch >>> 4);
            ch = (byte) (ch & 0x0F);    
            out.append(pseudo[ (int) ch]); 
            ch = (byte) (in[i] & 0x0F); 
            out.append(pseudo[ (int) ch]); 
     
            i++;
        }
     
        String rslt = new String(out);
        return rslt;
     
    }

    Doch leider bekomme ich bei Dateien die über 10 MB sind ein Out Of Memory und zwar auf Grund des String Buffers.
    Gibt es eine andere(bessere) Lösung?

    Viele Grüße und vielen Dank für eure Hilfe
     

  2. #2
    Avatar von Chefkoch333
    Chefkoch333 Chefkoch333 ist offline Mitglied Gold
    Registriert seit
    Apr 2007
    Beiträge
    112
    Die Frage ist ob du wirklich den kompletten Dateiinhalt im Speicher zur Verarbeitung benötigst oder würde auch ein Stream von Bytes ausreichen? Auf diese Art kannst du beliebig große Dateien verarbeiten.
     

  3. #3
    chocox chocox ist offline Mitglied
    Registriert seit
    Jul 2007
    Beiträge
    23
    Ok. Du meinst ich soll einen Stream aufmachen und alles was ich in dem StringBuffer schreibe z. Bsp. in einem ByteArrayOutputStream schreibe und diesen dann weiter verarbeite..?
     

  4. #4
    Avatar von zeja
    zeja zeja ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Sep 2006
    Beiträge
    2.962
    Ich frage mich warum du den Stream von dem du liest erst in ein ByteArray schreibst, statt diesen direkt zu verarbeiten und in deinen StringBuffer (StringBuilder ist übrigens schneller) zu schreiben? Dann hättest du das ganze auch nur einmal im Speicher. Die Frage ist wofür du das Resultat dann benötigst.
     

  5. #5
    chocox chocox ist offline Mitglied
    Registriert seit
    Jul 2007
    Beiträge
    23
    Ich lese einen AFP-Datenstrom (ähnlich PDF) in ein ByteArray ein. Dieses ByteArray wandle ich dann wie gesagt in Hex um, und hab somit die Möglichkeite den AFP-Datenstrom zu analysieren. Der Aufbau des AFP-Datenstroms ist in sogenannten Tripplets. Zum Beispiel steht das Tripplet X"D3A8A8" für Beginn Dokument. In einem AFP-Datenstrom werden Daten aufbereitet und zu einem Dokument zusammengefügt. Ich hab Content-Daten (XML oder LineData) und sogn. Ressourcen und Anweisungen wie die Daten aufbereitet werden. Ich hoffe die Erklärung ist einigermaßen verständlich. Also es geht darum diesen AFP-Datenstrom zu analysieren. Deshalb das ByteArray.
    Das mit dem Stream ist mir jetzt klar, aber ich will nicht in eine Datei schreiben, sondern müsste den Stream an ein Ziel (StringBuffer oder StringBuilder) weitergeben, damit ich ihn anschließend weiter verarbeiten kann.
    Und da harperts.
     

  6. #6
    Avatar von Vereth
    Vereth Vereth ist offline Mitglied Brokat
    Registriert seit
    Nov 2009
    Ort
    Dortmund
    Beiträge
    372
    Dann wandle den Datenstrom am besten sofort beim Lesen in einen Syntaxbaum oder ähnliches mit den entsprechenden Objekten um. Du brauchst dann nur einen kleinen Ausschnitt zu buffern.
    chocox bedankt sich. 
    Vielen Dank für die Nutzung des Bewerten- und Danke-Buttons

    Wenn man sieht, dass man einen anderen glücklich gemacht hat, ist die Welt um zwei glückliche Menschen reicher.

  7. #7
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.885
    Blog-Einträge
    29
    Hallo,

    ich hätte hier gar keinen StringBuffer verwendet, sondern gleich beim Einlesen den Datenstrom analysiert. Beispielsweise mit einem InputStreamFilter:
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    package de.tutorials;
     
    import java.io.FileInputStream;
    import java.io.FilterInputStream;
    import java.io.InputStream;
     
    public class HexReaderFilterExample {
        public static void main(String[] args) throws Exception {
            AFPInputStream afpInputStream = new AFPInputStream(new FileInputStream("/tmp/someFile"));
            System.out.println(afpInputStream.read());
            afpInputStream.close();
        }
     
        static class AFPInputStream extends FilterInputStream {
            protected AFPInputStream(InputStream in) {
                super(in);
            }
     
            //analyze input stream in read(...) Methods
        }
     
    }

    Gruß Tom
    chocox bedankt sich. 
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

  8. #8
    chocox chocox ist offline Mitglied
    Registriert seit
    Jul 2007
    Beiträge
    23
    Also ich habe jetzt probiert den Stream direkt in Hex umzuwandeln und das funktioniert auch, aber wenn ich dann daraus einen String machen will, weil ich in diesem nach den Tripplets suche, kommt jedesmal eine "Exception in thread "main" java.lang.OutOfMemoryError: Java heap space." Ich gebe bereits den Parameter -XX:+AggressiveHeap mit, der der JVM sagt, sie soll sich so viel Arbeitsspeicher schnappen wie möglich.
    Ich lese folgendermaßen den Stream ein und wandle ihn in Hex um:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    
        public static String getFile(File file) throws IOException{
     
            final ByteArrayOutputStream bo; 
            final long length = file.length();
            byte ch = 0x00;
            
            if(length < Integer.MAX_VALUE){
                bo = new ByteArrayOutputStream((int) length);
                bo.flush();
                
            }
            else
            {
                bo = new ByteArrayOutputStream(Integer.MAX_VALUE);
            }
            
            final FileInputStream in = new FileInputStream(file);
            int c;
            while((c = in.read()) != -1){
                
                
                String pseudo[] = {"0", "1", "2",
                         "3", "4", "5", "6", "7", "8",
                         "9", "A", "B", "C", "D", "E",
                         "F"};
     
                 ch = (byte) (c & 0xF0); // Strip off
                 ch = (byte) (ch >>> 4);
                 ch = (byte) (ch & 0x0F);  
                 
                 bo.write((pseudo[ (int) ch]).getBytes());
                 ch = (byte) (c & 0x0F); 
                 bo.write((pseudo[ (int) ch]).getBytes());
                        
            }
     
            String s = bo.toString(); //Da wirft er jedesmal den Fehler
            in.close();
            bo.close();
            
            return s;   
        }

    Anschließend möchte ich in diesen ewig langem String nach dem Muster X'D3A8A8 suchen, aber das kann ich nicht. Wie das mit dem FilterStreamInput funktionieren soll kann ich mir gerade nicht erklären.

    Vielen Dank für eure Hilfe.
    Geändert von chocox (10.01.10 um 00:07 Uhr)
     

  9. #9
    Avatar von Chefkoch333
    Chefkoch333 Chefkoch333 ist offline Mitglied Gold
    Registriert seit
    Apr 2007
    Beiträge
    112
    Es kann halt immer problematisch werden eine ganze Datei in den speicher zu laden. Zur Optimierung könntest du dir noch überlegen ob es nicht ausreichend ist einzelne Fragmente (ähnlich wie beim Sax parsen) einzuladen und zu verarbeiten. Kenne jetzt nicht deine Dateistruktur aber ein solche Fragment könnte dann eines deiner Tripplets sein...?
    Falls das auch nicht hilft gibt es noch die Möglichkeit die Datei einmal zu Indexen, d.h. einmal komplett durchzu-streamen und wichtige Positionen zu markieren. Danach bei der Abarbeitung kannst du dann via RandomAccessFile die Daten bei diesen Positionen lesen um so nur wirklich relevante Daten im Heap zu halten, oder du lädst die Datei gleich in eine DB und kannst die analyse dann mit hilfe von SQL durchführen.

    vg,
    ck.
     

Ähnliche Themen

  1. Buffer trennen
    Von Viper2009 im Forum C/C++
    Antworten: 21
    Letzter Beitrag: 13.06.07, 16:13
  2. buffer aufteilen
    Von tifa im Forum C/C++
    Antworten: 2
    Letzter Beitrag: 02.08.05, 22:32
  3. Buffer-Überlauf?
    Von NRFi im Forum C/C++
    Antworten: 3
    Letzter Beitrag: 29.03.04, 14:28
  4. Buffer overrun
    Von ASTROKSK im Forum Office-Anwendungen
    Antworten: 1
    Letzter Beitrag: 21.02.04, 07:54
  5. Buffer Underrun
    Von Vitalis im Forum Hardware
    Antworten: 6
    Letzter Beitrag: 05.04.02, 09:20