example c# unicode encoding unzip

example - zipfile c#



Letras alemanas y codificación en C# (2)

Pruebe CodePage 850 (me ha funcionado):

using (ZipArchive archive = System.IO.Compression.ZipFile.Open(ZipFile, ZipArchiveMode.Read, System.Text.Encoding.GetEncoding(850))) { // ....

El siguiente comentario es de (una versión antigua) de Sharpziplib que me puso en la dirección correcta:

/* Using the codepage 1252 doesn''t solve the 8bit ASCII problem :/ any help would be appreciated. // get encoding for latin characters (like ö, ü, ß or ô) static Encoding ecp1252 = Encoding.GetEncoding(1252); */ // private static Encoding _encoding = System.Text.ASCIIEncoding; private static Encoding _encoding = System.Text.Encoding.GetEncoding(850);

La última línea es mi cambio, para que sea correcta la lectura de archivos zip con caracteres especiales.

Tengo una función de descompresión, y estoy usando System.Text.Encoding para asegurarme de que los archivos que se están extrayendo conservan los mismos nombres después de la extracción, porque generalmente los archivos que estoy descomprimiendo contienen letras alemanas.
Intenté cosas diferentes, como Encoding.Default o Encoding.UTF8 pero nada funciona äÄéöÖüß.txt se convierte en „Ž‚”™á.txt o en caso de incumplimiento, se trata de cuadros negros: /

¿alguna sugerencia?

using (ZipArchive archive = System.IO.Compression.ZipFile.Open(ZipFile, ZipArchiveMode.Read, System.Text.Encoding.Default)) { foreach (ZipArchiveEntry entry in archive.Entries) { string fullPath = Path.Combine(appPath, entry.FullName); if (String.IsNullOrEmpty(entry.Name)) { Directory.CreateDirectory(fullPath); } else { if (!entry.Name.Equals("Updater.exe")) { entry.ExtractToFile(fullPath,true); } } } }


En primer lugar, el único formato ZIP oficial (no existente ...) no permite caracteres Unicode (entonces no puede usar ninguna codificación que no sea ASCII).

Dicho esto, muchas herramientas y bibliotecas le permiten usar una codificación diferente, pero puede fallar (por ejemplo, si intenta decodificar forzando UTF8 / UTF32 o lo que sea un archivo codificado con otra codificación).

Si el nombre del archivo está codificado en ASCII obtendrá la página de códigos de su sistema:

Para nombres de entrada que contienen solo caracteres ASCII, se establece el indicador de codificación de idioma y la página de códigos predeterminada del sistema actual se utiliza para codificar los nombres de las entradas.

No tienes un control tan grande con las clases de .NET sobre este tema. Pero si no especifica una codificación obtendrá un comportamiento predeterminado (UTF8 para códigos fuera de ASCII y página de códigos actual para ASCII). La mayoría de las veces funciona (si tanto la codificación como la decodificación se han realizado dentro de la misma página de códigos).

¿Cómo evitar esto? No es fácil (porque carecemos de un estándar) sino resumir:

  • No fuerce la codificación (a menos que esté consumiendo un archivo zip comprimido con una codificación conocida).
  • El comportamiento predeterminado es bastante bueno en la mayoría de los casos.
  • Para los archivos ZIP codificados en ASCII con caracteres extendidos, confíe en la página de códigos del sistema (debe ser la misma en ambos sistemas).
  • Brinde al usuario una forma de cambiar la codificación (no puede verificar qué codificación utiliza la utilidad zip y no hay un estándar sobre esto). Significa no solo cambiar la codificación (UTF8 / UTF16 o lo que sea) sino también la página de códigos (en caso de que no coincidan). La función GetEncoding te dará el codificador derecho para la página de códigos que especifiques).

La mejor pista que puedo darte? Confíe en el comportamiento predeterminado (es bastante común) pero proporcione una forma para que los usuarios lo cambien si necesita ser compatible con la mayoría de los códigos ZIP que existen (porque cada uno puede implementarse de una manera diferente), no solo para la codificación sino también para página de códigos también Especialmente no lo fuerce desde el código con la página de códigos específicos de Alemania porque romperá con el primer archivo en español / francés / italiano / holandés que manejará (y no hay una página de códigos común para ellos).

Por cierto, prepárese para manejar varias excepciones si abre un archivo con codificación incorrecta (no página de códigos).

Edición para futuros lectores (a partir de comentarios): CP 850 capta la mayoría de los caracteres comunes de Europa occidental, pero no es la página de códigos para Europa . Compárelo, por ejemplo, con los idiomas de Europa del Este o con Noruego. No coincide con ellos (y en esos idiomas, los caracteres fuera del rango 33-127 son bastante comunes porque no están dibujando cuadros). Algunos caracteres del CP 850 ( Ê Ë ı, por ejemplo) no están disponibles en (digamos) CP 865 (para el lenguaje Norsk).

Dejame explicarte con un ejemplo. Tiene un nombre de archivo (de Trukey) con este nombre: "Garip Dosya Adı.txt". El último carácter tiene el código 141 en CP 857 (para Turquía). Si usa el CP 850 obtendrá "en lugar de" porque en el CP 850 original tiene el código 213. Ni siquiera mencionaré los idiomas del lejano oriente (porque una página de códigos fija hará un desorden incluso si está limitado a Europa). Esta es la razón por la que no puede establecer una página de códigos fija a menos que esté escribiendo una pequeña utilidad para su propio uso.