日期:2014-05-20  浏览次数:20703 次

关于java中文件输入输出流的问题
一个简单的复制文件的程序,把e:/test1/java.doc 中的内容复制到 e:/test2/java.doc ,直接读取字节内容时可以完美复制,字体的格式什么的都可以复制成功。但是当我定义一个字符串变量str,使得str等于按字节读取的e:/test1/java.doc 文件中的内容后,再把str中的内容 输出到文件2中去,这时候文件2中就成了乱码了。
求解,是不是str 不应该是String 格式的,那应该是什么格式的
import java.io.*;
public class FileDemo {
public static void main (String[]args){
File source = new File("e:/test1/java.doc");
File target = new File("e:/test2/java.doc");
FileInputStream fis=null;
FileOutputStream fos=null;
try{
fis =new FileInputStream(source);
fos =new FileOutputStream(target);
    byte[] bytes =new byte[1024];
    int length;
    while((length=fis.read(bytes))!=-1){
     String str = new String(bytes,0,length);
     System.out.println(str);
    
     byte[] by = str.getBytes();
     fos.write(by);
    }
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}finally{
if(fis != null){
try{
fis.close();
}catch (IOException e){
e.printStackTrace();
}
}
if (fos != null){
try{
fos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}


}

}

------解决方案--------------------
doc是二进制文件,并非简单文本文件,也就是里面有大量是无法解释为非标准字符的。

String是字符串,组装为字符串时需要将读取到的byte转为char,由于前面说了doc并非文本文件,所以转换char的过程会有大量转换失败从而变成“?”字符,当然再写入新文件中就不再是原样了。

所以复制的最佳做法就是用 byte[] 基于字节数组来做,而且注意不能用FileReader,而是必须用FileInputStream
------解决方案--------------------
使用FileChannel的transferTo/transferFrom。
------解决方案--------------------
“那么在终端里显示出来还能组装成原来的格式吗”
显示出来就意味着要字符画,那么基本上就没希望重新组装了。

另外,你没法直接把doc文件内容显示出来,因为它不是简单的“文本文件”。
你可以尝试用POI之类的可以操作doc文件的开源组件来做,它能帮你解析doc文件,然后提供给你存取其中内容的函数。


附:如果因为某些场合非得将二进制转为字符形式,可以将其BASE64处理,需要还原时再反BASE64。