我正在java中使用socket开发一个http web服务器,它获取post头InputStream,然后我用一些由头'boundary'和'\r\n'分割的字符串处理头,并在HashMap中获取所有头、Cookie (s) 并获取字符串中的文件内容,并将该字符串保存到服务器上的文件中。当我将文本文件或 java 源文件上传到服务器时它工作正常,但如果是 doc、pdf 和图像,它会显示损坏的文件和损坏的图像。
PrintWriter out;
try {
out = new PrintWriter(new OutputStreamWriter(
new FileOutputStream(UploadPath + "\\" + FileName)));
out.print(FileData);
out.close();
} catch (Exception e) {
}
以上代码将使用“FileName”将“FileData”的内容保存在“UploadPath”处。
如果是 jpg 或 doc 文件,则 String FileData 具有由上述代码保存的上传文件的二进制内容,并且我还检查了两个文件的字节大小,并且两个文件的字节大小相同,并且我还匹配了内容通过调试应用程序来获取实际文件和内容 FileData String。
我还检查了实际上传的图像文件和 FileData 字符串,两者都逐字节匹配,但上传的图像完全损坏。
在互联网上搜索了一整天后,我无法找到解决方案。请帮忙。
我不想使用大多数页面上建议的 apache commons。
如果您想查看更多代码,我会将其发布。
最佳答案
当您处理二进制数据时,应该使用 byte
和 OutputStream
而不是 String
和 Writer
:如果将一些字节放入字符串中,它们是 decoded
因此,如果您找到了请求中二进制数据的边界(由字节数组表示),请将内容按字节直接复制到输出流。
只有当您的请求已完全存储在内存中时,此方法才有效。关于文件上传,这并不总是可能的,因为如果您有大文件,您可能会耗尽内存。
因此,实现文件上传的最佳方法是从流中仅读取下一个字节:这就是分割和解析之间的区别嗯>。实际上,您需要一个真正的解析器来处理多部分表单数据。现在事情变得复杂了,这就是每个人都使用 commons-fileupload 的原因:如果你的“前瞻”只是一些字节,那么检测边界并不那么容易。
出于法律原因,我必须实现洁净室实现。如果这不是您的情况,请查看 commons-fileupload 的源代码。看看RFC
关于java - 如何解析http header 以获取上传的文件并将其保存到磁盘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17009547/