【问题标题】:java FileNotFoundException Too many open filesjava FileNotFoundException 打开的文件太多
【发布时间】:2011-09-10 05:16:19
【问题描述】:

我正在尝试用 Java 构建一个自动备份脚本。虽然我不太擅长 Java,但事实证明这很困难。

这是我的代码:

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

【问题讨论】:

  • "自动备份脚本" 您是否考虑过为此使用 Ant?该脚本是供您使用,还是供 Intranet 使用,还是“在家中的最终用户”使用?

标签: java file file-io io copy


【解决方案1】:

确保您close() 两个您的:

  • ZipOutputStream(您这样做是正确的),并且
  • FileInputStream

现在,您的信息流中有许多打开的连接。

addFolderToZip() 方法中,在最后关闭FileInputStream,如下所示:

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

【讨论】:

  • ZipOutputStream 正在关闭。
  • @mre,是的,但不是FileOutputStream
  • 通过关闭ZipOutputStream,您隐式关闭了FileOutputStream
【解决方案2】:

关闭这些流的最佳做法是像这样在 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
     }
 }

【讨论】:

    【解决方案3】:
    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 !
    

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

    【讨论】:

      【解决方案4】:

      addFileToZip 中,只需在else 末尾添加in.close(),它应该可以解决问题。 当然,适当的代码也会检查异常,以便在出现问题时关闭流。

      【讨论】:

        猜你喜欢
        • 2017-11-09
        • 2019-09-17
        • 2011-06-29
        • 2011-05-16
        • 1970-01-01
        • 2017-09-09
        • 1970-01-01
        相关资源
        最近更新 更多