tutorials.de Buch-Aktion 05/2012
Seite 1 von 2 12 LetzteLetzte
ERLEDIGT
NEIN
ANTWORTEN
25
ZUGRIFFE
719
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Janitom Janitom ist offline Mitglied
    Registriert seit
    Aug 2011
    Beiträge
    15
    Hallo,

    ich habe folgendes Problem, ich lasse mehrere 7Zip Dateien (Datei.zip.001,...,Datei.zip.00x) mit den SequenceInputStream zusammenführen. Dies funktioniert soweit ganz gut, nur wenn ich die erhaltene Datei dann mit winrar oder Winzip öffnen will erscheint die Fehlermeldung unerwartetes Archivende.
    Weis jemand von vlt eine Lösung?

    Code java:
    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
    
    ....
     
    Object[] streamArray = streamsTemp.toArray();
            for(int i = streamArray.length-1; i >= 0; i--) {
               streams.addElement(streamArray[i]);
            }
            
            // Streams zusammenführen
            in = new SequenceInputStream(streams.elements());
        
            File zipTmp = new File(selectedDirectory  + System.getProperty("file.separator") + "Anhang");
            try {
                if (zipTmp.exists() == false){                                  
                    zipTmp.mkdir();
                }else if(zipTmp.exists()){
                    
                    out = new FileOutputStream(new File(selectedDirectory  + System.getProperty("file.separator") + "Anhang\\Datei.zip"), true); 
                    BufferedOutputStream bout = new BufferedOutputStream(out);
     
                    int bytes;          
                    while ((bytes = in.read()) != -1) { 
                        bout.write(bytes); 
                    } 
                    streamTmp.close();
                    in.close(); 
                    out.close(); 
                    bout.close();
                    //}
                }
            }
            catch( Exception ex ) {
                ex.printStackTrace();
            }
    ...
    Geändert von Janitom (03.08.11 um 15:08 Uhr)
     

  2. #2
    SE Tutorials.de Gastzugang
    Verwende mal anstatt des BufferedOutputStream einfach OutputStream. Oder wenns schon der BufferedOutputStream sein muss ein flush() am Ende.
    Außerdem kannst du nicht einfach so zwei eigenständige Zip-Files zusammenkopieren. Jedes Zip-File hat *unabhängig ob als Part oder regulär* File-Header und TOC. wenn du jetzt einfach alles zusamm kopierst *denn nichts anderes machst du* erhälts du einfach nur eine Aneinanderreihung. Das das ZIP nicht versteht liegt auf der Hand. Was du also machen müsstest wäre nun jedes Zip als ZipInputStream öffnen und einzeln alle Inhalte lesen , prüfen ob diese vollständig oder nur teilweise in jedem Part liegen , eventuell im RAM zusammenkopieren und dann in ein neues Zip mit einem ZipOutputStream völlig neu schreiben. Ein einfachs binäres zusammenkopieren funtkioniert bei Zip-Files nicht.
     

  3. #3
    Janitom Janitom ist offline Mitglied
    Registriert seit
    Aug 2011
    Beiträge
    15
    Wie prüfe ich denn Ob die vollständig sind? Den BufferedOutputStream hatte ich letztendlich nur genommen, um Geschwindigkeit zu gewinnen. Kann ich diese dann auch mit dem SequenceInputStream dann auch zusammenführen?

    Ich werd deinen Vorschlag mal versuchen.
    Geändert von Janitom (02.08.11 um 12:34 Uhr)
     

  4. #4
    SE Tutorials.de Gastzugang
    Erstmal : weg mit dem Buffered ... das bremst nur aus anstatt Geschindigkeit rauszuholen weil erst alles in den RAM geschrieben wird und dann vom RAM auf Platte. Das kannst du mit nem normalen OutputStream etwas abkürzen weil dieser dierekt auf das Ziel schreibt.

    Um mit Zip-Daten zu arbeiten klick mal auf meine Signatur und geht dann aufs Paket java.util.zip
    Da ist alles drin. Bei weiteren Fragen versuch ich dir zu helfen.
     

  5. #5
    Janitom Janitom ist offline Mitglied
    Registriert seit
    Aug 2011
    Beiträge
    15
    So nun will er aber nicht die Datei schreiben.... er erkennt dass dort nix drin ist im zipoutputstream


    Code java:
    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
    43
    44
    45
    
    ...
     
    if (archiveFiles.length == 1){
                                                    //
                                                    qZip = new FileInputStream(archiveFiles[k]);
                                                    streamsTemp.addElement(new ZipInputStream(qZip));                                       
                                                }                           
                                            }                                   
                                        }
                                    }
                                }
                            }
                            catch( Exception ex ) {
                                ex.printStackTrace();
                            }
    ...
     
    Object[] streamArray = streamsTemp.toArray();
            for(int i = streamArray.length-1; i >= 0; i--) {
               streams.addElement(streamArray[i]);
            }
            
            // Streams zusammenführen
            in = new ZipInputStream(new SequenceInputStream(streams.elements()));
        
            File zipTmp = new File(selectedDirectory  + System.getProperty("file.separator") + "Anhang");
            try {
                if (zipTmp.exists() == false){                                  
                    zipTmp.mkdir();
                }else if(zipTmp.exists()){
                    out = new FileOutputStream(new File(selectedDirectory  + System.getProperty("file.separator") + "Anhang\\Antrag.zip"), true);
                    zOut = new ZipOutputStream(out); 
                    
                    //File zipTmpFile = new File(selectedDirectory  + System.getProperty("file.separator") + "Anhang\\Antrag.zip");
                    
                    //if (zipTmpFile.exists() == false){
                        int len = 0;            
                        byte data[] = new byte[1024];
                        while ((len = in.read(data)) > 0) { 
                            zOut.write(data,0,len); 
                        } 
                        
                        in.close(); 
                        out.close(); 
                        zOut.close();
    Geändert von Janitom (03.08.11 um 15:07 Uhr)
     

  6. #6
    SE Tutorials.de Gastzugang
    Gut ... du hast die DOC scheinbar nicht verstanden.
    Von einem ZipInputStream liest man nicht via read(byte[]) und schreibt in einen ZipOutputStream auch nich via write(byte[], int, int).
    Du musst mit den ZipEntry arbeiten.

    Dessweiteren habe ich es mir noch mal durch den Kopf gehen lassen wie du überprüfst ob ein ZipEntry komplett in einem Zip-Part ist oder über mehrere verteilt :
    du musst erst von allen ZipFiles das TOC lesen und überprüfen ob es in mehreren Parts ein Entry mit dem selben Namen gibt. Dieses musst du dann im RAM erst zusammensetzen bevor du es schreiben kannst.

    Auch frage ich mal so :

    Wie meinst du das mit den Parts ?

    1) ein großes ZipFile wurd binär gesplittet ... also so das man erst aus allen Parts das originale File wieder zusammenkopieren muss
    2) die Funktion von Zip : Parted ... also das Zip wirklich einzelne komplette Zip-Files schreibt in denen die Daten verteilt sind

    Weil so wie du es versuchst wäre es 1) ... da du aber die Meldung : unerwartetes Archivende bekommst gehe ich davon aus das es in wirklichkeit 2) ist.
     

  7. #7
    Janitom Janitom ist offline Mitglied
    Registriert seit
    Aug 2011
    Beiträge
    15
    Genau kann ich das eigentlich nicht sagen, die Daten Stammen aus einer Fachanwendung, die über mehrere Nachrichten a 30mb versendet wurden. Diese Anhänge müssen dann wieder zusammengefügt werden, um diese entpacken zu können. Also war wohl mein Ansatz falsch, und ich würde sagen ich sollte es nach 2.) probieren.

    Edit: so ich versuche jetzt mal die tocs auszulesen ... hoffe es klappt

    Edit2:
    Code java:
    1
    2
    3
    4
    5
    
    java.util.zip.ZipException: invalid END header (bad central directory offset)
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.<init>(Unknown Source)
        at java.util.zip.ZipFile.<init>(Unknown Source)
        at source.ActionAssign.widgetSelected(ActionAssign.java:95)

    Edit3: So kleiner Fortschritt...er schreibt schonmal die Dateien aus der ersten gesplitteten Zip, blos am Ende dieser Zip meckert findet er keine Entries mehr folgender Code ist ein Test
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
            for (int j = 0;j < splittedZips.length; j++){
                //zFile = new ZipFile(splittedZips[j]);
                //zipEntries = zFile.entries();
                //zIn = splittedZips[j].;
                try {
                       zipIn = new ZipInputStream(new FileInputStream(splittedZips[j]));
                       while ((entry = zipIn.getNextEntry()) != null) {
                          String targetFileName;
                          targetFileName = entry.getName().substring(entry.getName().lastIndexOf("/")+1);
                          int read = 0;
                          byte[] data = new byte[1024];
                          FileOutputStream entryout = new FileOutputStream(selectedDirectory  + System.getProperty("file.separator") + "Anhang\\" + targetFileName);
                          while ((read = zipIn.read(data,0,1024)) != -1) {
                              entryout.write(data, 0, read);
                          }
                          entryout.close();
                       }
                       zipIn.close();
                    }
                    catch (Exception e) {
                       e.printStackTrace();
                    }
    }
    Geändert von Janitom (03.08.11 um 15:07 Uhr)
     

  8. #8
    Janitom Janitom ist offline Mitglied
    Registriert seit
    Aug 2011
    Beiträge
    15
    So ich habe rausgefunden, dass ich die Dateien nicht in das (ist ein Beispiel)

    Code java:
    1
    
    ZipFile zipFile = new ZipFile("c:\datei.zip.001))

    legen kann, dort kommt dann immer

    Exception in thread "main" java.util.zip.ZipException: error in opening zip file
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(Unknown Source)
    at java.util.zip.ZipFile.<init>(Unknown Source)
    at source.ZipArchiveExtractor.extractArchive(ZipArchiveExtractor.java:29)
    at source.ZipArchiveExtractor.main(ZipArchiveExtractor.java:19)
     

  9. #9
    SE Tutorials.de Gastzugang
    Hmm ... darf ich raten : du hast noch nie was von sog. Escape-Sequenzen gehört , richtig ?
    Mal davon abgesehen das du dich da oben vertippt hast und es anstatt
    Code java:
    1
    
    "001))
    eigentlich
    Code java:
    1
    
    "001");
    heißen müsste *String nicht geschlossen , letzte Klammer zu viel und vor allem fehlendes Semikolon* hast du nicht bedacht das ein Backslash "\" eine sog. Escape-Sequenz einleitet. Das Zeichen "\d" ist laut ASCII-Tabelle als "EOT" definiert *Hex 0x04*. Das du nun eine Exception bekommst liegt daran das es einfach kein File mit dem Namen
    Code :
    1
    
    C:[EOT]atei.zip.001
    gibt. Wenn du schon Backslashes in Pfadangaben verwenden willst weil du dich daran als Windows-User gewöhnt hast müsstest du es mindestens so schreiben :
    Code java:
    1
    
    ZipFile zipFile=new ZipFile("C:\\datei.zip.001");
    Ich rate dir aber lieber es dir gleich anzugewöhnen in Pfadangaben IMMER einen (Foreward)Slash "/" zu verwenden da dieser
    1) unter Unix sowieso verlangt wird *Linux , Mac* und "\\" kein gültiger Trenner ist
    2) er unter Windows durch sämtliche File-Klassen richtig dargestellt wird
    3) er auch das systemübergreifende Symbol in URLs und URIs ist die auch unter Windows so notiert werden und gültig sind
    4) es einfacher ist und plattformunabhängig

    Daher wundert es mich das eine so abstrakte Exception kommt und nicht eine viel niedrigere FileNotFoundException. Das der Compiler es überhaupt so übersetzt ist gleich das nächste was mich daran wundert.
     

  10. #10
    Janitom Janitom ist offline Mitglied
    Registriert seit
    Aug 2011
    Beiträge
    15
    Wie bereits vor dem Code steht: Es ist ein Beispiel, wollte es eigentlich mit dieser Zeile verständlicher machen, da er generell bei diesen Dateien diesen Fehler auswirft (getestet mit Beispielcode aus diesem Forum, wobei normale *.zip als ZipFile auch bei Initialisierung geöffnet werden können)


    Zwecks Pfadangaben, das entstand aus schnellen Versuchen, da ich direkt aus dem Explorer den Pfad übernommen habe. Diese habe ich natürlich bereits schon angepasst.

    bin übrigens schon etwas weiter gekommen
    Geändert von Janitom (03.08.11 um 19:26 Uhr)
     

  11. #11
    SE Tutorials.de Gastzugang
    Naja wenn du hier ein falsches Beispiel postest dann muss ich davon ausgehen das es im richtigen Code genau so falsch steht.
    Daher zwei Tipps :
    1) befolge das was ich oben geschrieben habe
    2) poste Beispiele genau so wie sie auch im richtigen Code stehen
     

  12. #12
    Janitom Janitom ist offline Mitglied
    Registriert seit
    Aug 2011
    Beiträge
    15
    Ok!
    Beim nächsten Mal werde ich daran denken.
    Danke dir erstmal. Für heut ist erstmal Schluss.
     

  13. #13
    Janitom Janitom ist offline Mitglied
    Registriert seit
    Aug 2011
    Beiträge
    15
    So neue Erkenntnis.....Die Dateien wurden vor dem Packen gezippt und anschließend in zb. 5MB Dateien binär aufgeteilt. Also werde ich jetzt versuchen die Dateien wieder binär zusammenzuführen und dann die erhaltene Zip entpacken.
     

  14. #14
    SE Tutorials.de Gastzugang
    Na das ist doch mal eine Information mit der sich was anfangen lässt.
    Ich würde jetzt allerdings nicht diesen Sequenced Stream nehmen sondern einfach über File.listFiles() mit n File-Array holen und die dann hinter ein andere öffnen , lesen , schließen. Und dabei bleibt der OutputStream auf das ZipFile immer offen und du schreibst da munter hinter ein ander rein.
    Danach solltest du es dann ohne Fehlermeldungen öffnen können.
     

  15. #15
    Janitom Janitom ist offline Mitglied
    Registriert seit
    Aug 2011
    Beiträge
    15
    Alles klar. Mit diesen Gedanken hatte ich auch gerade gespielt
    Ich meld mich wieder wenn es geklappt hat.
    Danke Dir.
     

Ähnliche Themen

  1. ZIP Archive mit java.utils.zip.* entpacken
    Von uwe75-1 im Forum Java
    Antworten: 3
    Letzter Beitrag: 23.01.11, 02:44
  2. 7zip mit Hilfe von PHP entpacken
    Von oeko im Forum PHP
    Antworten: 3
    Letzter Beitrag: 10.12.09, 14:42
  3. Antworten: 4
    Letzter Beitrag: 19.04.09, 12:21
  4. .tar Archive entpacken
    Von visiondpc im Forum PHP
    Antworten: 8
    Letzter Beitrag: 29.08.08, 09:46
  5. Split-Archive entpacken?
    Von defc0n1 im Forum Mac OS
    Antworten: 5
    Letzter Beitrag: 30.06.08, 07:14