在REST方法调用上上载的文件已损坏

所以我在我的Web应用程序中使用以下Rest方法来上传文件。 当我上传文本文件时,它们会正确保存,我可以打开它们。 但是在任何其他格式(即* .docx或* .pdf或* .jpg)的情况下,文件的存储大小与原始文件完全相同但已损坏。 以下是代码:

@POST @Consumes("multipart/form-data") public Response readFile() throws IOException, ServletException { Part filePart = request.getPart("c"); InputStream f = filePart.getInputStream(); String l = null; DataInputStream ds = new DataInputStream(f); File file = new File("c:\\temp\\" + getSubmittedFileName(filePart)); try { BufferedWriter bw = new BufferedWriter(new FileWriter(file)); while ((l = ds.readLine()) != null) { bw.write(l); } bw.flush(); bw.close(); return Response.status(201).entity("File Created").build(); } catch (Exception e) { e.printStackTrace(); } return Response.status(500).build(); } 

和html页面如下:

 


我假设必须有另一种方式来上传文件而不是这个。 我已经参考了如何使用JSP / Servlet将文件上传到服务器? 但我认为它没有说处理文件扩展名。 那么,我的代码出了什么问题?

我相信错误就在这里

 DataInputStream ds = new DataInputStream(f); ... while ((l = ds.readLine()) != null) { 

来自DataInputStream.readLine Javadoc

此方法无法将字节正确转换为字符。

您应该使用FileInputStream而不是DataInputStreamFileInputStream将所有文件视为字节。 除了上面提到的问题, readLine还会在读取输入文件中的所有换行符时删除。

编辑有关演示,请参阅下面的小片段。

文件dummy.txt包含

 foo bar 

foo之后的换行符是单个\n 。 在hex转储中它是

 66 6F 6F 0A 62 61 72 

现在使用DataInputStream读取文件一次,使用FileInputStream读取一次

 try (DataInputStream ds = new DataInputStream(new FileInputStream("dummy.txt")); Writer bw = new BufferedWriter(new FileWriter("out_writer.txt"))) { String l; while ((l = ds.readLine()) != null) { bw.write(l); } } try (InputStream in = new FileInputStream("dummy.txt"); OutputStream out = new FileOutputStream("out_inputstream.txt")) { byte[] buffer = new byte[8192]; int readBytes = -1; while ((readBytes = in.read(buffer)) > -1) { out.write(buffer, 0, readBytes); } } 

输出文件是

out_writer.txt

 ASCII: foobar hex : 66 6F 6F 62 61 72 

out_inputstream.txt

 ASCII: foo bar hex : 66 6F 6F 0A 62 61 72 

如您所见,在DataInputStream示例中删除了0A\n )。 这个规定的line break会使输出文件变得混乱。