2008-09-19 27 views
19

¿Cuál es la mejor manera de añadir no ASCII nombres de archivo en un archivo postal usando Java, de tal manera que los archivos pueden ser correctamente leídos ambos Windows y Linux?Añadir nombres de archivo no ASCII a zip en Java

Aquí hay un intento, adaptado de https://truezip.dev.java.net/tutorial-6.html#Example, que funciona en Windows Vista pero falla en Ubuntu Hardy. En Hardy, el nombre del archivo se muestra como abc-ЖДФ.txt en el archivo-rodillo.

import java.io.IOException; 
import java.io.PrintStream; 

import de.schlichtherle.io.File; 
import de.schlichtherle.io.FileOutputStream; 

public class Main { 

    public static void main(final String[] args) throws IOException { 

     try { 
      PrintStream ps = new PrintStream(new FileOutputStream(
        "outer.zip/abc-åäö.txt")); 
      try { 
       ps.println("The characters åäö works here though."); 
      } finally { 
       ps.close(); 
      } 
     } finally { 
      File.umount(); 
     } 
    } 
} 

diferencia de java.util.zip, TrueZIP permite especificar archivo zip codificación. Aquí hay otra muestra, esta vez especificando explícitamente la codificación. Ni IBM437, UTF-8 ni ISO-8859-1 funcionan en Linux. IBM437 funciona en Windows.

import java.io.IOException; 

import de.schlichtherle.io.FileOutputStream; 
import de.schlichtherle.util.zip.ZipEntry; 
import de.schlichtherle.util.zip.ZipOutputStream; 

public class Main { 

    public static void main(final String[] args) throws IOException { 

     for (String encoding : new String[] { "IBM437", "UTF-8", "ISO-8859-1" }) { 
      ZipOutputStream zipOutput = new ZipOutputStream(
        new FileOutputStream(encoding + "-example.zip"), encoding); 
      ZipEntry entry = new ZipEntry("abc-åäö.txt"); 
      zipOutput.putNextEntry(entry); 
      zipOutput.closeEntry(); 
      zipOutput.close(); 
     } 
    } 
} 
+0

truezip con UTF-8 trabajado para mí en Windows 7 y mac os x 10.6.x. Todavía no funciona en Linux? –

+1

Hubo un error de larga data, 9 años en existencia, en JDK anterior a la versión 7 que impedía el manejo correcto de nombres de archivos con nombres que no podían codificarse con IBM CP437. http://bugs.sun.com/bugdatabase/view_bug.do?bug%5Fid=4244499 Aparentemente se ha corregido en JDK7. https://blogs.oracle.com/xuemingshen/entry/non_utf_8_encoding_in Por lo tanto, una solución parece ser, use JDK7 y los nuevos constructores para ZipInputStream, ZipOutputStream y ZipFile. – Cheeso

Respuesta

0

¿De verdad falló o fue solo un problema de fuente? (por ejemplo, fuente que tiene glifos diferentes para esos códigos) He visto problemas similares en Windows donde el procesamiento "se rompió" porque la fuente no era compatible con el juego de caracteres pero la información en realidad estaba intacta y era correcta.

+0

Gracias por su respuesta, no es un problema de fuente porque puedo crear un archivo de nombre similar y luego comprimirlo y se mostrará correctamente. – Micke

0

Los nombres de archivo no ASCII no son confiables en las implementaciones ZIP y es mejor evitarlos. No hay ninguna disposición para almacenar una configuración de juego de caracteres en archivos ZIP; los clientes tienden a adivinar con 'la página de códigos del sistema actual', que es poco probable que sea lo que usted desea. Muchas combinaciones de cliente y página de códigos pueden dar como resultado archivos inaccesibles.

¡Lo siento!

+0

De acuerdo con las especificaciones de PKWare, existe una disposición para indicar que el nombre del archivo en cuestión está codificado con UTF-8. La codificación UTF-8 en archivos zip aún no es ampliamente compatible (== aún no es compatible con Windows Explorer). Cuando el bit UTF-8 está desactivado en el encabezado de entrada zip, la especificación zip dice que el nombre de archivo debe estar codificado en IBM437. Pero está en lo cierto, algunas aplicaciones (WinRar) solo codifican con la página de códigos predeterminada del sistema. No estoy seguro si Windows Explorer hace esto. No usar la codificación adecuada cuando se lee un archivo comprimido puede resultar en archivos inaccesibles. – Cheeso

3

De un vistazo rápido a la TrueZIP manual - que recomiendan el formato JAR:

Se utiliza UTF-8 para el nombre de archivo de codificación y comentarios - a diferencia de postal, que sólo utiliza IBM437.

Esto probablemente significa que la API está utilizando el paquete java.util.zip para su implementación; esa documentación indica que todavía está utilizando un ZIP format from 1996. El soporte de Unicode no se agregó al PKWARE .ZIP File Format Specification hasta 2006.

10

La codificación de las entradas de archivo en ZIP se especificó originalmente como IBM Code Página 437. Muchos caracteres utilizados en otros idiomas son imposibles de usar de esa manera.

El PKWARE-specification se refiere al problema y agrega un poco. Pero eso es una adición posterior (desde 2007, gracias a Cheeso por aclarar eso, ver comentarios). Si ese bit está configurado, la entrada de nombre de archivo debe estar codificada en UTF-8. Esta extensión se describe en 'APÉNDICE D - Codificación de idioma (EFS)', que se encuentra al final del documento vinculado.

Para Java es un error conocido, tener problemas con caracteres que no sean ASCII. Consulte bug #4244499 y la gran cantidad de errores relacionados.

Mi colega utilizó como solución URL la codificación para los nombres de los archivos antes de almacenarlos en el ZIP y decodificarlos después de leerlos. Si controla ambos, almacenando y leyendo, puede ser una solución.

EDITAR: En el error que alguien sugiere usar el ZipOutputStream de Apache Ant como solución alternativa. Esta implementación permite la especificación de una codificación.

+0

"Parece estar históricamente especificado como IBM CP437" es un poco flexible. La especificación PKWare dice que los nombres de archivo usan IBM437 para la codificación, punto. En 2007, PKWare agregó una forma estándar de usar UTF-8. ¡Hay herramientas que no usan ninguna, pero eso está fuera de la especificación! – Cheeso

+1

Gracias por aclararme, cambié la respuesta. – Mnementh

+1

escribió "si ese bit está configurado, todas las entradas de nombre de archivo deben estar codificadas en UTF-8". Esto no es correcto. El uso de UTF-8 o IBM437 es por entrada, no por archivo. Un archivo comprimido que cumpla con la especificación puede contener algunas entradas con nombres codificados en UTF-8 y otros codificados en IBM437. – Cheeso

8

En archivos Zip, de acuerdo con la especificación de PKWare, la codificación de los nombres de archivos y comentarios de archivos es IBM437. En 2007 PKWare amplió la especificación para permitir también UTF-8. Esto no dice nada sobre la codificación de los archivos contenidos en el zip. Solo la codificación de los nombres de archivo.

Creo que todas las herramientas y bibliotecas (Java y no Java) son compatibles con IBM437 (que es un superconjunto de ASCII), y menos herramientas y bibliotecas admiten UTF-8. Algunas herramientas y libs son compatibles con otras páginas de códigos. Por ejemplo, si comprime algo utilizando WinRar en una computadora que se ejecuta en Shanghai, obtendrá la página de códigos Big5. Esto no está "permitido" por la especificación zip, pero sucede de todos modos.

La biblioteca DotNetZip para .NET hace Unicode, pero por supuesto eso no ayuda si está usando Java!

Al utilizar el soporte integrado de Java para ZIP, siempre obtendrá IBM437. Si desea un archivo con algo que no sea IBM437, utilice una biblioteca de terceros o cree un JAR.

+2

¿Por qué downvoted anonymously? ¿No te gusta la información precisa? – Cheeso

+2

Todavía no estoy seguro de por qué esta respuesta está siendo downvoted. Es * aún * información precisa y correcta. Si alguien tiene alguna objeción, o si alguien piensa que la información en esta respuesta es incorrecta, por favor hable. – Cheeso

8

Milagros de hecho ocurren, y Sun/Oracle sabían realmente fijan el de larga vida bug/RFE:

Ahora es posible set up filename encodings upon creating el archivo zip/corriente (requiere Java 7).

+0

Ese enlace está muerto http: //img819.imageshack.us/img819/4199/croppercapture6l.jpg – Cheeso

+2

Aquí hay una publicación de blog, en vivo desde junio de 2012, sobre el Milagro: https://blogs.oracle.com/xuemingshen/entry/non_utf_8_encoding_in – Cheeso

Cuestiones relacionadas