为什么我的图像出现乱码?

发布于 2024-07-05 13:42:36 字数 2579 浏览 7 评论 0原文

我有一些 Java 代码,使用 servlet 和 Apache Commons FileUpload 将文件上传到设置的目录。 它对于字符数据(例如文本文件)工作正常,但图像文件出现乱码。 我可以打开它们,但图像看起来不正常。 这是我的代码:

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) 看起来像:

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

最后 FileManager.createFile 看起来像:

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

谁能发现我做错了什么?

干杯, 李

I've got some Java code using a servlet and Apache Commons FileUpload to upload a file to a set directory. It's working fine for character data (e.g. text files) but image files are coming out garbled. I can open them but the image doesn't look like it should. Here's my 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) looks like:

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

And finally FileManager.createFile looks like:

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

Can anyone spot what I'm doing wrong?

Cheers,
Lee

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

伴随着你 2024-07-12 13:42:37

您能否对原始文件和上传的文件执行校验和,看看是否存在任何直接差异?

如果有,那么您可以查看执行比较,以确定文件中缺少更改的确切部分。

浮现在脑海中的是流的开始或结束,或者字节顺序。

Can you perform a checksum on your original file, and the uploaded file and see if there is any immediate differences?

If there are then you can look at performing a diff, to determine the exact part(s) of the file that are missing changed.

Things that pop to mind is beginning or end of stream, or endianness.

一萌ing 2024-07-12 13:42:37

我只是使用 commons io 然后你可以做一个 IOUtils.copy(InputStream, OutputStream) ;

它还有许多其他有用的实用方法。

I'd just use commons io Then you could just do an IOUtils.copy(InputStream, OutputStream);

It's got lots of other useful utility methods.

涫野音 2024-07-12 13:42:37

我不知道它有什么区别,但方法签名似乎不匹配。 在 doPost() 方法中调用的 getBytes() 方法只有一个参数:

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

而您包含的方法源有两个参数:

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

希望有所帮助。

I don't know what difference it makes, but there seems to be a mismatch of method signatures. The getBytes() method called in your doPost() method has only one argument:

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

while the method source you included has two arguments:

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

Hope that helps.

熟人话多 2024-07-12 13:42:37

您确定图像没有出现乱码或者您没有在传入过程中丢失一些数据包吗?

Are you sure that the image isn't coming through garbled or that you aren't dropping some packets on the way in.

轻拂→两袖风尘 2024-07-12 13:42:36

我不喜欢的一件事是 StreamUtils.getBytes() 中的这个块:

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

在第 6 行,无论读入多少字节,它都会写入整个缓冲区。我不相信情况总是如此。 这样会更正确:

 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 }

注意第 5 行的“else”,以及第 6 行的两个附加参数(数组索引起始位置和要复制的长度)。

我可以想象,对于较大的文件(例如图像),缓冲区在它被填满之前返回(也许它正在等待更多)。 这意味着您会无意中写入保留在缓冲区尾部的旧数据。 假设缓冲区 > ,这几乎肯定会在 EoF 的大部分时间发生。 1 个字节,但 EoF 处的额外数据可能不是导致损坏的原因......这只是不可取的。

One thing I don't like is here in this block from StreamUtils.getBytes():

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

At line 6, it writes the entire buffer, no matter how many bytes are read in. I am not convinced this will always be the case. It would be more correct like this:

 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 }

Note the 'else' on line 5, along with the two additional parameters (array index start position and length to copy) on line 6.

I could imagine that for larger files, like images, the buffer returns before it is filled (maybe it is waiting for more). That means you'd be unintentionally writing old data that was remaining in the tail end of the buffer. This is almost certainly happening most of the time at EoF, assuming a buffer > 1 byte, but extra data at EoF is probably not the cause of your corruption...it is just not desirable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文