Pourquoi mes images apparaissent-elles brouillées ?

Si vous êtes un développeur Java utilisant des servlets et des téléchargements de fichiers, vous avez peut-être rencontré un problème frustrant : des images téléchargées qui semblent brouillées ou corrompues lorsqu’elles sont ouvertes. Cela peut être déroutant, surtout si les fichiers texte se téléchargent sans aucun problème. Dans cet article de blog, nous allons explorer pourquoi cela se produit et fournir des solutions claires pour résoudre le problème.

Comprendre le problème

Lorsqu’on travaille avec des téléchargements de fichiers, en particulier des fichiers image, il est essentiel de gérer correctement les données binaires. La sortie brouillée indique généralement que le flux binaire n’est pas lu correctement ou n’est pas écrit dans le fichier de manière appropriée. Le segment de code ci-dessous montre une méthode typique de téléchargement de fichiers utilisant Apache Commons FileUpload :

protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    ...
    BufferedInputStream stream = new BufferedInputStream(item.openStream());
    ...
}

Dans cette méthode, les images et d’autres fichiers binaires sont traités, mais la manière dont les données sont lues peut entraîner des problèmes qui corrompent les fichiers image.

Analyser le code

Une partie clé du code qui contribue au problème se trouve dans la méthode de lecture des octets du flux d’entrée. Voici le segment de code pertinent :

public static byte[] getBytes(InputStream src, int buffsize) throws IOException {
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    byte[] buff = new byte[buffsize];

    while (true) {
        int nBytesRead = src.read(buff);
        if (nBytesRead < 0) {
            break;
        }
        byteStream.write(buff);
    }
    ...
}

Identification du problème

  • Écriture de tout le buffer : La ligne byteStream.write(buff); écrit l’intégralité du buffer, peu importe le nombre d’octets qui ont réellement été lus. Cela pose problème car, dans de nombreux cas, nBytesRead sera inférieur à la taille du buffer, ce qui signifie que des octets restants des lectures précédentes peuvent être écrits dans la sortie, entraînant une corruption.

Solution suggérée

Pour résoudre ce problème, nous devons ajuster la manière dont les octets sont écrits dans le ByteArrayOutputStream. Le code révisé devrait ressembler à ceci :

public static byte[] getBytes(InputStream src, int buffsize) throws IOException {
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    byte[] buff = new byte[buffsize];

    while (true) {
        int nBytesRead = src.read(buff);
        if (nBytesRead < 0) {
            break;
        } else {
            byteStream.write(buff, 0, nBytesRead); // N'écrire que les octets lus
        }
    }
    ...
}

Modifications clés

  1. Écriture conditionnelle : La clause else garantit que nous n’écrivons que les octets qui ont réellement été lus.
  2. Longueur spécifiée : Lors de l’écriture, nous spécifions désormais le nombre d’octets à écrire, en utilisant byteStream.write(buff, 0, nBytesRead);.

Ces changements empêchent les anciennes données inutiles d’être écrites et garantissent que les fichiers image sont préservés sans corruption.

Conclusion

Si vous rencontrez des problèmes avec les téléchargements d’images dans votre application Java, le coupable se cache souvent dans la manière dont vous gérez le flux d’entrée. En affinant votre logique de lecture et d’écriture des flux d’octets, vous pouvez éliminer les problèmes qui conduisent à des images brouillées.


En suivant les lignes directrices ci-dessus et en corrigeant la manière dont vous lisez et écrivez les flux d’octets, vous pouvez prévenir de futurs maux de tête liés aux téléchargements de fichiers dans vos applications Java. Bon codage !