[英]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
你在产生多个线程吗?
您必须详细了解您的环境:
我的系统配置如下:
$ 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.