我有一些使用servlet和Apache Commons FileUpload的Java代码将文件上传到set目录。它对字符数据(例如文本文件)工作正常,但图像文件出现乱码。我可以打开它们,但图像看起来不应该。这是我的代码:
的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();
}
有人能发现我做错了吗?
干杯, 利
答案 0 :(得分:4)
我不喜欢的一件事是来自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发生的,假设一个缓冲区&gt; 1个字节,但EoF的额外数据可能不是你腐败的原因......这是不可取的。
答案 1 :(得分:1)
我只使用commons io然后你就可以做一个IOUtils.copy(InputStream,OutputStream);
它有许多其他有用的实用方法。
答案 2 :(得分:0)
你确定图像没有出现乱码,或者你没有丢弃一些数据包。
答案 3 :(得分:0)
我不知道它有什么不同,但似乎方法签名不匹配。 getBytes()
方法中调用的doPost()
方法只有一个参数:
byte[] bytes = StreamUtils.getBytes(stream);
虽然您包含的方法源有两个参数:
public static byte[] getBytes(InputStream src, int buffsize)
希望有所帮助。
答案 4 :(得分:0)
您是否可以对原始文件和上传的文件执行校验和,看看是否存在任何直接差异?
如果有,那么您可以查看执行差异,以确定缺少的文件的确切部分发生了变化。
想到的东西是流的开始或结束,或者是字节序。