Domanda

Io ho un codice Java che utilizza una servlet e Apache Commons FileUpload per caricare un file in una directory del set.Funziona bene per i dati di carattere (ad es.il file di testo), ma i file di immagine sono venuta incomprensibili.Posso aprire loro, ma l'immagine non guardare come dovrebbe.Ecco il mio codice:

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), assomiglia a questo:

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

E, infine, FileManager.createFile, assomiglia a questo:

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

Qualcuno può spot che cosa sto facendo di sbagliato?

Ciao Lee

È stato utile?

Soluzione

Una cosa che non mi piace è qui, in questo blocco da StreamUtils.getBytes():

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

Alla riga 6, scrive l'intero buffer, non importa quanti byte sono leggere.Io non sono convinto che questo sarà sempre il caso.Sarebbe più corretto così:

 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 }

Nota il 'resto', sulla linea 5, insieme con gli altri due parametri (indice di un array posizione di inizio e la lunghezza di copia) sulla linea 6.

Posso immaginare che per file di grandi dimensioni, come le immagini, il buffer restituisce la prima è pieno (forse è in attesa per più).Questo significa che devi essere involontariamente la scrittura di dati vecchi che era rimasto in coda del buffer.Questo è quasi certamente accade la maggior parte del tempo a EoF, assumendo un buffer > 1 byte, ma extra dati a EoF è probabilmente la causa del tuo livello di corruzione...non solo è auspicabile.

Altri suggerimenti

Vorrei solo utilizzare commons io Quindi si potrebbe fare solo un IOUtils.copia(InputStream, OutputStream);

Ha un sacco di altre utili metodi di utilità.

Sei sicuro che l'immagine non è venuta attraverso la distorta o non cadere alcuni pacchetti sul modo in.

Non so che differenza fa, ma sembra che ci sia una mancata corrispondenza di firme di metodo.Il getBytes() metodo chiamato nel doPost() il metodo ha un solo argomento:

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

mentre il metodo sorgente è incluso dispone di due argomenti:

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

Speranza che aiuta.

Si può eseguire un checksum del file originale e il file da caricare e vedere se c'è qualche immediato differenze?

Se non ci sono allora si può guardare in esecuzione di un diff, per determinare l'esatta parte(i) del file sono mancanti cambiato.

Cose che pop in mente è l'inizio o la fine del flusso, o endianness.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top