IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Java Discussion :

Patch probleme java.util.zip


Sujet :

Contribuez Java

  1. #1
    Membre confirmé Avatar de billynirvana
    Homme Profil pro
    Architecte technique
    Inscrit en
    Décembre 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2004
    Messages : 472
    Points : 552
    Points
    552
    Par défaut Patch probleme java.util.zip
    Bonjour,

    Le package java.util.zip génère une exception lors de la décompression de fichiers dont le nom comporte des caractères non UTF-8.

    La résolution de ce bug est vivement souhaitée par les développeurs des 4 coins du monde, d'où sa présence à la 2ème place du top 25 des bugs JAVA:

    http://bugs.sun.com/bugdatabase/top25_bugs.do

    De plus, lors de la compression, le nom des entrées est mal converti pour les mêmes raisons.

    Je propose de corriger ce bug ici et de l'envoyer à SUN pour l'inclure dans une prochaine release. (why not)


    J'ai commencé à y jetter un coup d'oeil pour la décompression, et j'arrive à décompresser des fichiers ZIP avec des caractères accentués sans générer d'exception.


    Vous trouverez l'ensemble des classes en PJ:
    - Le ZipInputStream qui pose problème et qui a subit quelques modifs de ma part.
    - ZipConstant n'a pas changé mais comme les constantes ne sont pas publiques, alors il a été nécessaire de le copier dans le package.
    - ZipUtils, ma classe utilitaire ZIP, exploitable, mais pas dans sa version finale.


    Utilisation: disposer de documents avec des accents ou autres caractères mal gérés dans le répertoire test, créés à la racine du projet ; les zipper avec Winzip (nom=fromWinzip.zip), Winrar (nom=fromWinrar.zip).

    Exemple d'utilisation dans un petit test.java contenant un petit main:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public static void main(String[] args) {
    	String path = "test/";
     
    	try {
    		ZipUtils.compress(path, new File(path+"fromJAVAZIP.zip"));
     
    		ZipUtils.decompress(new File(path + "fromWinzip.zip"), path + "/unzippedWINZIP");
    		//ZipUtils.decompress(new File(path + "fromWInrar.zip"), path + "/unzippedWINRAR");
    		//ZipUtils.decompress(new File(path + "fromJAVAZIP.zip"), path + "/unzippedJAVAZIP");
     
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    }


    Pour ceux qui sont vraiment experts, et qui peuvent se passer de ce genre de tests, voici là où le problème se pose:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    	/**
             * Fetches a UTF8-encoded String from the specified byte array.
             */
    	private static String getUTF8String(byte[] b, int off, int len) {
    		// First, count the number of characters in the sequence
    		int count = 0;
    		int max = off + len;
    		int i = off;
    		while (i < max) {
    			int c = b[i++] & 0xff;
    			switch (c >> 4) {
    			case 0:
    			case 1:
    			case 2:
    			case 3:
    			case 4:
    			case 5:
    			case 6:
    			case 7:
    				// 0xxxxxxx
    				count++;
    				break;
    			case 12:
    			case 13:
    				// 110xxxxx 10xxxxxx
    				if ((int) (b[i++] & 0xc0) != 0x80) {
    					throw new IllegalArgumentException();
    				}
    				count++;
    				break;
    			case 14:
    				// 1110xxxx 10xxxxxx 10xxxxxx
    				if (((int) (b[i++] & 0xc0) != 0x80)
    						|| ((int) (b[i++] & 0xc0) != 0x80)) {
    					throw new IllegalArgumentException();
    				}
    				count++;
    				break;
    			default:
    				// 10xxxxxx, 1111xxxx
    				throw new IllegalArgumentException();
    			}
    		}
    		if (i != max) {
    			throw new IllegalArgumentException();
    		}
    		// Now decode the characters...
    		char[] cs = new char[count];
    		i = 0;
    		while (off < max) {
    			int c = b[off++] & 0xff;
    			switch (c >> 4) {
    			case 0:
    			case 1:
    			case 2:
    			case 3:
    			case 4:
    			case 5:
    			case 6:
    			case 7:
    				// 0xxxxxxx
    				cs[i++] = (char) c;
    				break;
    			case 12:
    			case 13:
    				// 110xxxxx 10xxxxxx
    				cs[i++] = (char) (((c & 0x1f) << 6) | (b[off++] & 0x3f));
    				break;
    			case 14:
    				// 1110xxxx 10xxxxxx 10xxxxxx
    				int t = (b[off++] & 0x3f) << 6;
    				cs[i++] = (char) (((c & 0x0f) << 12) | t | (b[off++] & 0x3f));
    				break;
    			default:
    				// 10xxxxxx, 1111xxxx
    				throw new IllegalArgumentException();
    			}
    		}
     
    		return new String(cs, 0, count);
    	}
     
    	private String getZipEntryName(byte[] b, int off, int len) {
    		String result = null;
     
    		try {
    			result = new String(b, off, len, "UTF-8");
    		} catch (UnsupportedEncodingException e) {
    			result = new String(b, off, len);
    		}
     
    		return result;
    	}
    Dans la version originale, l'appel se fait avec getUTF8String et le plantage se situe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    			default:
    				// 10xxxxxx, 1111xxxx
    				throw new IllegalArgumentException();

    Ma solution a consisté pour le moment à bifurquer l'appel vers getZipEntryName.

    Mais je bloque, d'où la demande de la contribution de personnes plus confirmées que moi.


    Cordialement,


    Billy


    EDIT: SystemUtils est une autre classe non incluse en PJ
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    FILE_SEPARATOR = System.getProperty("file.separator");
    FILE_ENCODING = System.getProperty("file.encoding");
    Fichiers attachés Fichiers attachés

  2. #2
    Membre confirmé Avatar de billynirvana
    Homme Profil pro
    Architecte technique
    Inscrit en
    Décembre 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2004
    Messages : 472
    Points : 552
    Points
    552
    Par défaut
    Je n'avais pas précisé, avec cette version, si on décompresse une archive zip compressé avec cette API, alors les noms sont correctements restitués.

    Par contre, dézipper cet archive avec Winzip ne restitue pas correctement les noms des fichiers accentués.

    Quel encodage utilise Winzip???

    Merci de votre collaboration.


    Billy

Discussions similaires

  1. probleme avec java.util.zip
    Par tarekphp dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 13/05/2009, 18h36
  2. Java.util.zip : decompresser un fichier zip
    Par kam81 dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 22/07/2007, 12h45
  3. problème avec java.util.zip.Inflater
    Par felix79 dans le forum Collection et Stream
    Réponses: 1
    Dernier message: 11/06/2007, 15h02
  4. Importer java.utils.zip ?
    Par Chii-san dans le forum Java ME
    Réponses: 3
    Dernier message: 15/03/2007, 15h01
  5. [C#] #ziplib ou J# (java.util.zip) pour ZIPper?
    Par SErhio dans le forum Windows Forms
    Réponses: 10
    Dernier message: 11/02/2005, 15h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo