Frage

Ich habe Java-Code, der ein Servlet und Apache Commons FileUpload verwendet, um eine Datei in ein festgelegtes Verzeichnis hochzuladen.Es funktioniert gut für Zeichendaten (z. B.Textdateien), aber Bilddateien werden verstümmelt ausgegeben.Ich kann sie öffnen, aber das Bild sieht nicht so aus, wie es sollte.Hier ist mein 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) sieht so aus:

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

Und schließlich sieht FileManager.createFile so aus:

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

Kann jemand erkennen, was ich falsch mache?

Prost, Lee

War es hilfreich?

Lösung

Eine Sache, die mir nicht gefällt, ist hier in diesem Block von StreamUtils.getBytes():

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

In Zeile 6 wird der gesamte Puffer geschrieben, egal wie viele Bytes eingelesen werden.Ich bin nicht davon überzeugt, dass dies immer der Fall sein wird.Richtiger wäre es so:

 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 }

Beachten Sie das „else“ in Zeile 5 sowie die beiden zusätzlichen Parameter (Startposition des Array-Index und zu kopierende Länge) in Zeile 6.

Ich könnte mir vorstellen, dass bei größeren Dateien wie Bildern der Puffer zurückkehrt, bevor er gefüllt ist (vielleicht wartet er auf weitere Dateien).Das bedeutet, dass Sie unbeabsichtigt alte Daten schreiben würden, die am hinteren Ende des Puffers verblieben sind.Dies passiert mit ziemlicher Sicherheit die meiste Zeit bei EoF, vorausgesetzt, dass der Puffer > 1 Byte ist, aber zusätzliche Daten bei EoF sind wahrscheinlich nicht die Ursache für Ihre Beschädigung ... es ist einfach nicht wünschenswert.

Andere Tipps

Ich würde es einfach verwenden Commons io Dann könnten Sie einfach einen IOUtils.copy(InputStream, OutputStream);

Es verfügt über viele weitere nützliche Hilfsmethoden.

Sind Sie sicher, dass das Bild nicht verstümmelt ankommt oder dass Sie unterwegs keine Pakete verlieren?

Ich weiß nicht, welchen Unterschied es macht, aber es scheint eine Diskrepanz zwischen den Methodensignaturen zu geben.Der getBytes() Methode, die in Ihrem aufgerufen wird doPost() Methode hat nur ein Argument:

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

während die von Ihnen eingefügte Methodenquelle zwei Argumente hat:

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

Hoffentlich hilft das.

Können Sie eine Prüfsumme für Ihre Originaldatei und die hochgeladene Datei erstellen und feststellen, ob es unmittelbare Unterschiede gibt?

Wenn dies der Fall ist, können Sie einen Vergleich durchführen, um die genauen Teile der Datei zu ermitteln, die fehlen und geändert wurden.

Dinge, die mir in den Sinn kommen, sind der Anfang oder das Ende des Streams oder Endianness.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top