繁体   English   中英

Java中打开的文件太多

[英]Too many open files in Java

我多次称这种方法:

  private static void writeFile(double val, String myFile) throws IOException { FileWriter file = new FileWriter(myFile, true); file.write(val + "\\n"); file.close(); } 

在periode之后我有这个例外:

 Exception in thread "main" java.io.FileNotFoundException: myFile (Too many open files) 

我怎么能解决这个例外呢?

我猜你的文件写入中的一些(可能全部)会导致异常,这会使file.close()短路。 即使不是这种情况,通常的做法是将文件IO操作包装在try / catch / finally中,以确保无论读/写是否成功,您打开的任何内容都将被关闭。 如果不关闭文件,则会用完句柄。

private static void writeFile(double val, String myFile) throws IOException {
    FileWriter file = null;
    try {
        file = new FileWriter(myFile, true);
        file.write(val + "\n");
    } catch( IOException e ) {
        e.printStackTrace();
    } finally {
        if( file != null ) {
            file.close();
        }
    }
}

或者,如果使用JDK 1.7:

private static void writeFile(double val, String myFile) throws IOException {
    try (FileWriter file = new FileWriter(myFile, true)) {
        file.write(val + "\n");
    } catch( IOException e ) {
        e.printStackTrace();
    }
}

如前所述,由于某些IOException,close可能没有完成,因此在Java 7中:

private static void writeFile(double val, String myFile) throws IOException {
    try (FileWriter file = new FileWriter(myFile, true)) {
        file.write(val + "\n");
    }
}

问题出现了:代码是否隐藏了异常?

然而, 真正的原因是你可能或多或少地同时写入同一个文件。 对于这种工作,记录器更适合。

使用java.util.logging:

private static void writeFile(double val, String myFile) throws IOException {
    Logger.getLogger(MyClass.class.getName()).log(Level.INFO, "" + val);
}

logging.properties您可以使用文件记录器为MyClass,使用原样输出格式。

我正在写我的机器上的1000000文件,我没有收到任何错误。

import java.io.FileWriter;
import java.io.IOException;

public class ManyFiles {
    private static void writeFile(double val, String myFile) throws IOException {
        FileWriter file = new FileWriter(myFile, true);
        file.write(val + "\n");
        file.close();
    }

    public static void main(String[] args) {
        for (int i = 0; i < 1000000; i++) {
            try {
                writeFile(i + 1.0, "/tmp/scratch/" + i);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

对我来说,所有文件都是生成的,没有失败:

$ ls /tmp/scratch | wc -l
1000000

你在产生多个线程吗?

您必须详细了解您的环境:

  • 您使用的是哪种操作系统?
  • 您使用的是哪个JDK版本?
  • 什么是硬件配置?
  • 您正在运行此程序的用户是否有任何系统限制?

我的系统配置如下:

$ uname -a
Linux box01 3.11.8-300.fc20.x86_64 #1 SMP Wed Nov 13 16:34:27 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
$ javac -version
javac 1.7.0_45
$ java -version
java version "1.7.0_45"
OpenJDK Runtime Environment (fedora-2.4.3.0.fc20-x86_64 u45-b15)
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)
$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 62970
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

一个粗略的想法是每次打开文件时执行System.out.println()或写入日志文件,每次关闭它时。 当它崩溃时,查看日志以打开而不关闭。
另一个考虑因素是,如果您调用函数的速度快于它在文件上执行打开/关闭的速度。 在这种情况下,同步块可能对您的函数有用,以防止并发访问。

当您打算使用任何外部资源并打开资源以开始使用时, 使用Java 7新功能Try-with-resource
这个新功能过于有用,因为您忘记在打开后关闭资源,它会在使用后自动关闭该资源。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM