【问题标题】:Print Writer does corrupt files when its used to upload files to a serverPrint Writer 用于将文件上传到服务器时会损坏文件
【发布时间】:2013-02-12 14:54:00
【问题描述】:

晚上好,今天我在使用 Print Writer 将文件上传到服务器时遇到了一个奇怪的情况,文件被传输了我尝试使用 FileOutPutStream 代替它解决了问题,我的问题是为什么 PrintWriter 会这种奇怪的行为,这是我在上传文件并将其保存在服务器时使用的代码:

public void doPost(HttpServletRequest request,HttpServletResponse response)throws IOException,ServletException{
int i;
if(request instanceof MultipartWrapper){

String DestinationPath="C:\\";
MultipartWrapper request1=(MultipartWrapper)request;
File f=request1.getFile("photo");
java.io.FileInputStream fis=new java.io.FileInputStream(f);
//PrintWriter out=new PrintWriter(DestinationPath+f.getName()); causes the problem mentioned above  
java.io.FileOutputStream out=new java.io.FileOutputStream(DestinationPath+f.getName());
while((i=fis.read())!=-1){
out.write(i);
}
fis.close();
out.close();


}

}

【问题讨论】:

    标签: java servlets printwriter


    【解决方案1】:

    您需要了解 Writers 和 OutputStreams 之间的区别。 PrintWriter.write(int) 正在写一个字符,而FileOutputStream.write(int) 正在写一个字节。您不小心将字节转换为字符,这会损坏您的文件。一般来说,当只是复制流时,你希望坚持字节。

    【讨论】:

      【解决方案2】:

      PrintWriter 将使用默认编码创建一个 Writer,而 FileOutputStream 将简单地写出原始字节。如果您的原始内容和服务器端使用相同的编码,您将不会遇到写入字节和重新解释它们的问题。但是,当您使用 PrintWriter 时,会使用默认系统编码,这可能会破坏您的数据。

      【讨论】:

      • 无论使用何种编码,读取字节并将它们写入字符都会被破坏(可能是单字节编码除外)。
      • @jtahlborn 我没有看到 OP 的服务器端代码,但他可能也在服务器端读取字节
      • 服务器端无关紧要。如果客户端默认编码是多字节,则数据在离开客户端之前将被破坏(或者如果单字节编码更改了某些无效字符)。
      • 好吧,那我错过了什么。如果我将字符串的字节写出(以它们碰巧的任何编码),然后在另一端将字节读入byte[],然后在服务器端使用public String(byte[] bytes) 对其进行解码> 默认编码是ascii,我不会把数据弄出来吧?我知道我们在这里偏离了 OP 的原始问题;)
      • 正如我所说,如果客户端默认编码是单字节编码,它不会替换无效字符,那么它将“工作”(因此您的示例使用“ascii”,它是单一的-byte,虽然我认为 java ascii 编码是 7bit,而不是 8bit,所以可能仍然会导致损坏)。服务器做了什么是无关紧要的(假设它在发送之前没有损坏数据)。