Question

J'ai du code Java utilisant un servlet et Apache Commons FileUpload pour télécharger un fichier dans un répertoire défini.Cela fonctionne bien pour les données de caractères (par ex.fichiers texte) mais les fichiers image sortent tronqués.Je peux les ouvrir mais l'image ne ressemble pas à ce qu'elle devrait être.Voici mon code :

Servlet

protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    try {
      String customerPath = "\\leetest\\";

      // Check that we have a file upload request
      boolean isMultipart = ServletFileUpload.isMultipartContent(request);

      if (isMultipart) {
        // Create a new file upload handler
        ServletFileUpload upload = new ServletFileUpload();

        // Parse the request
        FileItemIterator iter = upload.getItemIterator(request);
        while (iter.hasNext()) {
          FileItemStream item = iter.next();
          String name = item.getFieldName();
          if (item.isFormField()) {
            // Form field.  Ignore for now
          } else {
            BufferedInputStream stream = new BufferedInputStream(item
                .openStream());
            if (stream == null) {
              LOGGER
                  .error("Something went wrong with fetching the stream for field "
                      + name);
            }

            byte[] bytes = StreamUtils.getBytes(stream);
            FileManager.createFile(customerPath, item.getName(), bytes);

            stream.close();
          }
        }
      }
    } catch (Exception e) {
      throw new UploadException("An error occured during upload: "
          + e.getMessage());
    }
}

StreamUtils.getBytes(stream) ressemble à :

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);
    }

    byte[] result = byteStream.toByteArray();
    byteStream.close();

    return result;
}

Et enfin FileManager.createFile ressemble à :

public static void createFile(String customerPath, String filename,
      byte[] fileData) throws IOException {
    customerPath = getFullPath(customerPath + filename);
    File newFile = new File(customerPath);
    if (!newFile.getParentFile().exists()) {
      newFile.getParentFile().mkdirs();
    }

    FileOutputStream outputStream = new FileOutputStream(newFile);
    outputStream.write(fileData);
    outputStream.close();
  }

Quelqu'un peut-il repérer ce que je fais de mal ?

Bravo, Lee

Était-ce utile?

La solution

Une chose que je n'aime pas se trouve ici dans ce bloc de StreamUtils.getBytes() :

 1 while (true) {
 2   int nBytesRead = src.read(buff);
 3   if (nBytesRead < 0) {
 4     break;
 5   }
 6   byteStream.write(buff);
 7 }

À la ligne 6, il écrit l’intégralité du tampon, quel que soit le nombre d’octets lus.Je ne suis pas convaincu que ce sera toujours le cas.Ce serait plus correct comme ceci :

 1 while (true) {
 2   int nBytesRead = src.read(buff);
 3   if (nBytesRead < 0) {
 4     break;
 5   } else {
 6     byteStream.write(buff, 0, nBytesRead);
 7   }
 8 }

Notez le « autre » sur la ligne 5, ainsi que les deux paramètres supplémentaires (position de début de l'index du tableau et longueur à copier) sur la ligne 6.

Je pourrais imaginer que pour les fichiers plus volumineux, comme les images, le tampon revient avant d'être rempli (peut-être qu'il attend plus).Cela signifie que vous écririez involontairement d’anciennes données qui restaient à la fin du tampon.Cela se produit presque certainement la plupart du temps à EoF, en supposant un tampon > 1 octet, mais des données supplémentaires à EoF ne sont probablement pas la cause de votre corruption... ce n'est tout simplement pas souhaitable.

Autres conseils

j'utiliserais simplement communs io Ensuite, vous pouvez simplement faire un IOUtils.copy(InputStream, OutputStream);

Il contient de nombreuses autres méthodes utilitaires utiles.

Êtes-vous sûr que l'image n'est pas tronquée ou que vous ne perdez pas de paquets en chemin.

Je ne sais pas quelle différence cela fait, mais il semble y avoir une inadéquation entre les signatures de méthodes.Le getBytes() méthode appelée dans votre doPost() La méthode n'a qu'un seul argument :

byte[] bytes = StreamUtils.getBytes(stream);

tandis que la source de méthode que vous avez incluse a deux arguments :

public static byte[] getBytes(InputStream src, int buffsize)

J'espère que cela pourra aider.

Pouvez-vous effectuer une somme de contrôle sur votre fichier d'origine et sur le fichier téléchargé et voir s'il y a des différences immédiates ?

Si c'est le cas, vous pouvez envisager d'effectuer une comparaison, pour déterminer la ou les parties exactes du fichier qui manquent de modifications.

Les choses qui me viennent à l'esprit sont le début ou la fin du flux, ou l'endianité.

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