在Java中复制文件

4

请问为什么我的输出文件末尾会出现字符 "ÿ"?(我使用try/catch)

        File f1 = new File("C:/Users/NetBeansProjects/QuestionOne/input.txt");
        File f2 = new File("C:/Users/NetBeansProjects/QuestionOne/output.txt");
        fin = new FileInputStream(f1);
        fout = new FileOutputStream(f2);

        do {
            i = fin.read();
            fout.write(i);

        } while (i != -1);

代码复制了文件内容,但以奇怪的字符结尾。 我需要把整个代码都包含进去吗?
谢谢。

1
为什么要重复造轮子呢?Apache Commons IO已经有这个功能了。 - user330315
4个回答

13

fin.read() 方法在没有可读内容时返回 -1;但您实际上正在将该值 -1 写入 fout,即使它并未出现在 fin 中。这会显示为 ÿ 字符。

避免此问题的一种方法是更改您的循环:

    while((i = fin.read()) != -1 ){
        fout.write(i);
    } 

2
+1 另外考虑使用 BufferedInputStreamBufferedOutputStream 以获得更好的性能。 - Eng.Fouad

5

因为最后一个fin.read()不会读取任何内容。根据JavaDoc,它将返回-1,因此您的fout.write(i)将写入该-1。您可以像这样做来更正这种行为:

do {
  i = fin.read();
  if (i>-1) //note the extra line
   fout.write(i);
} while (i != -1);

或者将do .. while更改为while .. do调用。

我建议您也应该查看新的NIO API,它将比每次传输一个字符表现得更好。

File sourceFile = new File("C:/Users/NetBeansProjects/QuestionOne/input.txt");  
File destFile = new File("C:/Users/NetBeansProjects/QuestionOne/output.txt");   

FileChannel source = null;                                                      
FileChannel destination = null;                                                 

try {                                                                           
    if (!destFile.exists()) {                                                   
        destFile.createNewFile();                                               
    }                                                                           
    source = new FileInputStream(sourceFile).getChannel();                      
    destination = new FileOutputStream(destFile).getChannel();                  
    destination.transferFrom(source, 0, source.size());                         
} catch (IOException e) {                                                       
    System.err.println("Error while trying to transfer content");               
    //e.printStackTrace();                                                      
} finally {                                                                     
    try{                                                                        
    if (source != null)                                                         
        source.close();                                                         
    if (destination != null)                                                    
        destination.close();                                                    
    }catch(IOException e){                                                      
        System.err.println("Not able to close the channels");                   
        //e.printStackTrace();                                                  
    }                                                                           
} 

5

尝试使用Java 7引入的新文件类(Files class)

public static void copyFile( File from, File to ) throws IOException {
    Files.copy( from.toPath(), to.toPath() );
}

1

或者你可以在输出之前检查 if(i != -1)

do {
    i = fin.read();
    if(i != -1)
    fout.write(i);
   } while (i != -1);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接