Question

Mon objectif est d'encoder un fichier et de le compresser dans un dossier en Java.Je dois utiliser la bibliothèque Commons-codec d'Apache.Je suis capable de l'encoder et de le compresser et cela fonctionne bien, mais lorsque je le décode dans sa forme originale, il semble que le fichier n'ait pas été complètement encodé.On dirait qu'il manque quelques pièces.Quelqu'un peut-il me dire pourquoi cela se produit ?

Je joins également la partie de mon code pour votre référence afin que vous puissiez me guider en conséquence.

private void zip() {
    int BUFFER_SIZE = 4096;
    byte[] buffer = new byte[BUFFER_SIZE];

    try {
        // Create the ZIP file
        String outFilename = "H:\\OUTPUT.zip";
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
                outFilename));

        // Compress the files
        for (int i : list.getSelectedIndices()) {
            System.out.println(vector.elementAt(i));
            FileInputStream in = new FileInputStream(vector.elementAt(i));
            File f = vector.elementAt(i);

            // Add ZIP entry to output stream.
            out.putNextEntry(new ZipEntry(f.getName()));

            // Transfer bytes from the file to the ZIP file
            int len;

            while ((len = in.read(buffer)) > 0) {
                buffer = org.apache.commons.codec.binary.Base64
                        .encodeBase64(buffer);
                out.write(buffer, 0, len);

            }

            // Complete the entry
            out.closeEntry();
            in.close();

        }

        // Complete the ZIP file
        out.close();
    } catch (IOException e) {
        System.out.println("caught exception");
        e.printStackTrace();
    }
}
Était-ce utile?

La solution

Les données codées en BASE64 sont généralement plus longues que la source, mais vous utilisez la longueur des données source pour écrire codées dans le flux de sortie.

Vous devez utiliser la taille du tableau généré au lieu de votre variable len.

Deuxième avis - ne pas redéfinir buffer chaque fois que vous codez un octet.Écrivez simplement le résultat dans la sortie.

 while ((len = in.read(buffer)) > 0)  {                         
     byte [] enc = Base64.encodeBase64(Arrays.copyOf(buffer, len));
     out.write(enc, 0, enc.length);
 }

MISE À JOUR:Utiliser Arrays.copyOf(...) pour définir la longueur du tampon d’entrée pour le codage.

Autres conseils

Votre principal problème est que le codage base64 ne peut pas être appliqué par bloc (surtout pas l'implémentation Apache-commons).Ce problème s'aggrave car vous ne savez même pas quelle est la taille de vos blocs car cela dépend des octets lus par in.read(..).

Vous avez donc deux alternatives :

  1. Chargez le fichier complet en mémoire, puis appliquez l'encodage base64.
  2. utilisez une implémentation alternative d'encodeur Base64 qui fonctionne en fonction du flux (le projet Apache Batik semble contenir une telle implémentation : org.apache.batik.util.Base64EncoderStream)

Lorsque vous lisez le contenu du fichier dans tampon vous obtenez len octets.Lorsque la base64 codant sur cela, vous obtenez plus que len octets, mais vous n'écrivez toujours que len octets au fichier.Ces haricots que la dernière partie de vos morceaux de lecture sera tronqué.

En outre, si votre lecture ne remplit pas le tampon entier, vous ne devez pas baser64 encoder plus que len octets car vous serez autrement suivre 0s dans le rembourrage des derniers octets.

Combinaison des informations ci-dessus Cela signifie que vous devez baser64 encoder l'ensemble du fichier (luttez-le dans un octet []), à moins que vous ne puissiez garantir que chaque morceau que vous lisez peut correspondre exactement à un message codé de base64.Si vos fichiers ne sont pas très importants, je vous recommanderais de lire le fichier entier.

Un problème plus petit est que, lorsque vous lisez dans votre boucle, vous devriez probablement vérifier "> -1", pas "> 0", mais contre son cas, il ne fait pas de différence.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top