为什么我的图像出现乱码?
时间:2020-03-05 18:47:02 来源:igfitidea点击:
我有一些Java代码,使用servlet和Apache Commons FileUpload将文件上传到设置的目录。对于字符数据(例如文本文件),它工作正常,但图像文件出现乱码。我可以打开它们,但是图像看起来不应该。这是我的代码:
小服务程序
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(); }
谁能发现我在做什么错?
干杯,
背风处
解决方案
回答
我们确定图像没有出现乱码,还是在途中没有丢掉一些数据包。
回答
我不知道它有什么区别,但是方法签名似乎不匹配。在doPost()方法中调用的getBytes()方法只有一个参数:
byte[] bytes = StreamUtils.getBytes(stream);
而我们包括的方法源有两个参数:
public static byte[] getBytes(InputStream src, int buffsize)
希望能有所帮助。
回答
我们可以对原始文件和上载的文件执行校验和,看看是否存在立即差异吗?
如果有的话,我们可以看一下进行比较,以确定丢失的文件的确切部分是否已更改。
突然想到的事情是流的开始或者结束或者字节序。
回答
我不喜欢的一件事是来自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行上的两个添加参数(数组索引起始位置和要复制的长度)。
我可以想象对于较大的文件(例如图像),缓冲区在填充之前返回(也许正在等待更多)。这意味着我们将无意中写入保留在缓冲区尾端的旧数据。假设缓冲区> 1个字节,这几乎肯定会在EoF上大多数时间发生,但是EoF上的额外数据可能不是造成损坏的原因……这是不希望的。
回答
我将使用commons io然后可以执行IOUtils.copy(InputStream,OutputStream);
它还有许多其他有用的实用程序方法。