2014-05-21 24 views
9

Chcę spakować plik w systemie Windows (7) przy pomocy ZipOutputStream. Problem polega na tym, że nazwa pliku (oraz plik Treści też) zawiera również znaki greckie ("ГП0000660040140521_a.txt", Gamma i Pi). Kod zip plik używać:"IllegalArgumentException: UNMAPPABLE [1]" podczas kompresowania pliku greckimi znakami

ZipOutputStream zipOs = new ZipOutputStream(
    new FileOutputStream("c:\\temp\\test.zip"), Charset.forName("cp737") 
); 

File sourceFile = new File("C:/Path/To/File/ГП0000660040140521_b.txt"); 
String entryName = sourceFile.getName().replaceAll("\\\\", "/"); 
ZipEntry entry = new ZipEntry(entryName); 
zipOs.putNextEntry(entry); 
... 
... 

Ale w ostatnim wierszu (wywołanie putNextEntry) dostaję IllegalArgumentException:

java.lang.IllegalArgumentException: UNMAPPABLE[1] 
at java.util.zip.ZipCoder.getBytes(ZipCoder.java:95) 
at java.util.zip.ZipOutputStream.writeLOC(ZipOutputStream.java:407) 
at java.util.zip.ZipOutputStream.putNextEntry(ZipOutputStream.java:221) 

Przypuszczam, że musi być coś nie tak z mapowania znaków pomiędzy Grecki i UTF-8 ... Jaki jest właściwy sposób na spakowanie pliku z greckimi znakami w nazwie pliku?

EDIT

Jeśli używam „UTF-8”, jak ustawić postać pliku ZIP mogą być tworzone, ale nazwa pliku skompresowanego jest źle: „ðôðƒ0000660040140521_a.txt” (greckie znaki brakuje)

+0

Do czego służy metoda createZipEntry? – agad

+0

@agad: Mój błąd! Poprawiłem kod. Dzięki. – Steffen

+0

Kiedy mówisz, że nazwa jest "zła", jak dokładnie to weryfikujesz? Z którego narzędzia korzystasz do sprawdzania pliku ZIP i czy na pewno używasz tego samego kodowania do interpretacji nazw plików użytych podczas ich tworzenia? –

Odpowiedz

0

Napisałem tę (późną) odpowiedź z powodu komentarzy "miso" i "kriegax" mojego pytania.

Jeśli dobrze pamiętam, czytałem wszędzie, że obsługa plików UTF8 w plikach zip jest jednym z największych słabych punktów plików zip (ponieważ UTF-8 nie jest oficjalnie obsługiwany przez standard zip?!?). Mogą być teraz istniejące aplikacje zip, które obsługują kodowanie UTF-8 w nazwach plików.

Jednak. W naszym przypadku mogliśmy zastąpić greckie znaki "zwykłymi" znakami ("a ... z"), ponieważ pliki do zip zostały wygenerowane przez drukarkę fiskalną, a zawiera w każdym przypadku tylko jedną grecką postać : "PI" (tylko obejście ...).

+0

Problem z ZIP polega na tym, że nie zawiera żadnych meta informacji o rzeczywistym kodowaniu (kodowaniu) używanym do kodowania nazw plików. – miso

0

Od ZipCoder używanego przez ZipOutputStream używa mapowania skonfigurowany, aby zawsze wyjątek, gdy postać nie może być odwzorowany, skończyło się na przekształcenie entryName do określonego zestawu znaków najpierw siebie, a potem po prostu dzwoniąc ZipEntry entry = new ZipEntry(entryName). Możesz to zrobić na przykład w ten sposób:

new String(input.getBytes(charset), charset) 

Zapewnia to, że wszystkie niepoprawne znaki są konwertowane na znaki zastępcze i nie ma wyjątków.

Wypróbuj to i prawdopodobnie zauważysz kilka znaków kontrolnych Unicode (które nie nadają się do edycji) na oryginalnym wejściu.