2011-06-07 98 views
3

我想在Java中建立一个自动备份脚本。虽然我对Java并不擅长,但事实证明这很困难。java FileNotFoundException太多打开的文件

这里是我的代码:

package javatest; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipOutputStream; 

public class Main { 
public static void main(String[] args) throws Exception { 
     String path = "/mnt/192.168.1.89"; 
     String destFile = "/home/scott/backup.zip"; 

     zip(path,destFile); 
} 

private static void zip(String src, String destFile) throws Exception 
{ 
    FileOutputStream fileWriter = new FileOutputStream(destFile); 
    ZipOutputStream zip = new ZipOutputStream(fileWriter); 

    addFolderToZip("", src, zip); 

    zip.flush(); 
    zip.close(); 
} 

private static void addFolderToZip(String path, String srcFolder, ZipOutputStream zip) throws Exception 
{ 
     File folder = new File(srcFolder); 

     for (String filename : folder.list()) 
     { 
      if (path.equals("")) { 
       addFileToZip(folder.getName(), srcFolder + "/" + filename, zip); 
      } else { 
       addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + filename, zip); 
      } 
     } 
} 

private static void addFileToZip(String path, String srcFile, ZipOutputStream zip) throws Exception 
{ 
    File folder = new File(srcFile); 

    if (folder.isDirectory()) { 
      addFolderToZip(path,srcFile,zip); 
    } else { 
      byte[] buf = new byte[1024]; 

      int len; 

      FileInputStream in = new FileInputStream(srcFile); 

      zip.putNextEntry(new ZipEntry(path + "/" + folder.getName())); 

      while((len = in.read(buf)) > 0) 
      { 
       zip.write(buf,0,len); 
      } 
    } 
} 
} 

而这里的例外:

Exception in thread "main" java.io.FileNotFoundException: FILENAME (Too many open files) 
    at java.io.FileInputStream.open(Native Method) 
    at java.io.FileInputStream.<init>(FileInputStream.java:106) 
    at java.io.FileInputStream.<init>(FileInputStream.java:66) 
    at javatest.Main.addFileToZip(Main.java:53) 
    at javatest.Main.addFolderToZip(Main.java:37) 
    at javatest.Main.addFileToZip(Main.java:47) 
    at javatest.Main.addFolderToZip(Main.java:37) 
    at javatest.Main.addFileToZip(Main.java:47) 
    at javatest.Main.addFolderToZip(Main.java:37) 
    at javatest.Main.addFileToZip(Main.java:47) 
    at javatest.Main.addFolderToZip(Main.java:37) 
    at javatest.Main.addFileToZip(Main.java:47) 
    at javatest.Main.addFolderToZip(Main.java:37) 
    at javatest.Main.addFileToZip(Main.java:47) 
    at javatest.Main.addFolderToZip(Main.java:37) 
    at javatest.Main.addFileToZip(Main.java:47) 
    at javatest.Main.addFolderToZip(Main.java:37) 
    at javatest.Main.addFileToZip(Main.java:47) 
    at javatest.Main.addFolderToZip(Main.java:35) 
    at javatest.Main.zip(Main.java:22) 
    at javatest.Main.main(Main.java:14) 
Java Result: 1 
+0

“自动备份脚本”你有没有考虑使用Ant此?这个脚本是供你使用,还是为了内部网,或者'最终用户在家'? – 2011-06-07 16:14:35

回答

1

确保您close()双方你:

  • ZipOutputStream(你正确地这样做了),和
  • FileInputStream

现在,您的流中有许多开放式连接。

addFolderToZip()方法,关闭FileInputStream末像这样:

try { 
    in.close(); 
} catch (IOException e) { 
    //Log exception 
} 
+0

'ZipOutputStream'正在关闭。 – mre 2011-06-07 16:06:07

+0

@mre,是的,但不是'FileOutputStream'。 – 2011-06-07 16:10:53

+0

通过关闭'ZipOutputStream',你隐式关闭'FileOutputStream'。 – mre 2011-06-07 16:11:48

0
FileInputStream in = new FileInputStream(srcFile); 

zip.putNextEntry(new ZipEntry(path + "/" + folder.getName())); 
while((len = in.read(buf)) > 0) 
{ 
    zip.write(buf,0,len); 
} 
in.close(); //You have to close file ! 

你必须关闭文件时,你不需要它了

0

addFileToZip,只是做in.close()在其他的结尾,它应该做的伎俩。 当然,即使出现问题,正确的代码也会检查异常以关闭流。

1

关闭这些流,最好的做法是做在的try-finally块,像这样(finally块几乎总是在try块退出执行

private static void zip(String src, String destFile) throws Exception 
{ 
    FileOutputStream fileWriter=null; 
    ZipOutputStream zip = null; 
    try{ 
    fileWriter = new FileOutputStream(destFile) 
    zip = new ZipOutputStream(fileWriter); 

    addFolderToZip("", src, zip); 

    zip.flush(); 
    }finally{ 
    if(zip!=null)zip.close();//close also does a flush 
    if(fileWriter!=null)fileWriter.close(); 
    } 
} 

private static void addFileToZip(String path, String srcFile, ZipOutputStream zip) throws Exception 
{ 
    File folder = new File(srcFile); 

    if (folder.isDirectory()) { 
      addFolderToZip(path,srcFile,zip); 
    } else { 
      byte[] buf = new byte[1024]; 

      int len; 

      FileInputStream in = null; 
      try{ 
       in = new FileInputStream(srcFile); 
       zip.putNextEntry(new ZipEntry(path + "/" + folder.getName())); 

       while((len = in.read(buf)) > 0) 
       { 
        zip.write(buf,0,len); 
       } 
      }finally{if(in!=null)in.close()}//<<--ensure in is closed you forgot this in the example code 
    } 
} 
+0

用于释放'finally'块中的资源 – mre 2011-06-07 17:05:58