Mijn doel is om een servlet een zip-file met txt-bestanden te laten uitpoepen. Dit leek te lukken, tot de zip-file corrupt bleek. Na een hoop gefrot heb ik maar een stand-alone testcase gemaakt, die de essentie van het probleem weergeeft:
Het lijkt wat omslachtig om van zip weer de bytes te nemen en dat naar een file te schrijven, maar uiteindelijk wordt zip dus gewoon in de output van de HttpResponse geschreven. Dit is dus een faire 'simulatie'. Deze code werkt gewoon op mijn WinXP bak (java 1.4.2_03_b02). De zip die echter op de productieserver (RedHat, java 1.4.2_04-b05) wordt gegenereerd met deze code, is corrupt:
Overigens ben ik ook al andere foutmelding over een corrupte central directory tegengekomen. Detail: als ik de zip extract op mijn Mac, is er geen vuiltje aan de lucht (volgens mij ignored die alle CRC fouten?!), maar het is duidelijk geen valid zip bestand.
Nu is het zo dat ik 3 plekken gemarkeerd heb in de sourcecode van mijn test. Al deze methoden zijn ook overloaded met een argument voor de encoding. Als die niet opgegeven wordt, kiest java de def. encoding van het platform (volgens API). Nu dacht ik mijn probleem op te lossen door expliciet een encoding op te geven bij 1, 2 en 3. Als ik dat doe, levert me dat op zowel WinXP en RedHat een corrupte zip op
(Zowel met de waarde "UTF8" als "ASCII"). Ik ben er wel achter gekomen dat als ik alleen bij 1 een (willekeurige) encoding opgeef en bij de rest niet, dat het dan op WinXP wel goed gaat, maar op RedHat nog steeds niet. Als ik alleen op 2 of 3 (of op allebei) de encoding meegeef, dan gaat het ook op WinXP niet goed.
Wie kan mij helpen? Dit domme gedoe kost me nu al vele uren en er lijkt niet echt een logisch patroon richting een oplossing in te zitten..
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
| public class ZipTester{ public static void main(String args[]){ try{ ByteArrayOutputStream bout = new ByteArrayOutputStream(); ZipOutputStream zout = new ZipOutputStream(bout); byte[] b = "test".getBytes(); // **1 ZipEntry zEntry = new ZipEntry("test.txt"); zEntry.setSize(b.length); zout.putNextEntry(zEntry); zout.write(b,0,b.length); zout.closeEntry(); zout.finish(); zout.flush(); bout.flush(); String zip = bout.toString(); // **2 bout.close(); FileOutputStream fout = new FileOutputStream(new File("test.zip")); fout.write(zip.getBytes()); // **3 } catch(Exception e){ System.out.println("help! : " + e); } } } |
Het lijkt wat omslachtig om van zip weer de bytes te nemen en dat naar een file te schrijven, maar uiteindelijk wordt zip dus gewoon in de output van de HttpResponse geschreven. Dit is dus een faire 'simulatie'. Deze code werkt gewoon op mijn WinXP bak (java 1.4.2_03_b02). De zip die echter op de productieserver (RedHat, java 1.4.2_04-b05) wordt gegenereerd met deze code, is corrupt:
code:
1
2
3
4
5
6
| WinZip test.zip output: Use Path: no Overlay Files: yes Extracting test.txt bad CRC d87f7e0c (should be 3f7f7e0c) Warning: the size of the extracted file (4) does not match the uncompressed size (0) recorded in the zip file |
Overigens ben ik ook al andere foutmelding over een corrupte central directory tegengekomen. Detail: als ik de zip extract op mijn Mac, is er geen vuiltje aan de lucht (volgens mij ignored die alle CRC fouten?!), maar het is duidelijk geen valid zip bestand.
Nu is het zo dat ik 3 plekken gemarkeerd heb in de sourcecode van mijn test. Al deze methoden zijn ook overloaded met een argument voor de encoding. Als die niet opgegeven wordt, kiest java de def. encoding van het platform (volgens API). Nu dacht ik mijn probleem op te lossen door expliciet een encoding op te geven bij 1, 2 en 3. Als ik dat doe, levert me dat op zowel WinXP en RedHat een corrupte zip op
Wie kan mij helpen? Dit domme gedoe kost me nu al vele uren en er lijkt niet echt een logisch patroon richting een oplossing in te zitten..
[ Voor 4% gewijzigd door Sammy op 24-05-2005 15:22 ]