Java 在爪哇语中:“;“打开的文件太多”;从网络路径读取时出错
我有下面的代码,它只是从一个文件夹中读取所有文件。此文件夹中有20000个文件。该代码在本地文件夹(Java 在爪哇语中:“;“打开的文件太多”;从网络路径读取时出错,java,networking,io,Java,Networking,Io,我有下面的代码,它只是从一个文件夹中读取所有文件。此文件夹中有20000个文件。该代码在本地文件夹(d:/files)上运行良好,但在读取大约1000-2000个文件后在网络路径(//robot/files)上失败 更新:文件夹是彼此的副本 是什么导致此问题以及如何解决此问题 package cef_debug; import java.io.*; public class Main { public static void main(String[] args) throws T
d:/files
)上运行良好,但在读取大约1000-2000个文件后在网络路径(//robot/files
)上失败
更新:文件夹是彼此的副本
是什么导致此问题以及如何解决此问题
package cef_debug;
import java.io.*;
public class Main {
public static void main(String[] args) throws Throwable {
String folder = args[0];
File[] files = (new File(folder)).listFiles();
String line;
for (int i = 0; i < files.length; i++) {
BufferedReader br = new BufferedReader(new FileReader(files[i]));
while ((line = br.readLine()) != null) {
}
br.close();
}
}
}
第12行是:
BufferedReader br = new BufferedReader(new FileReader(files[i]));
尝试:
package-cef\u调试;
导入java.io.*;
公共班机{
公共静态void main(字符串[]args)抛出可丢弃的{
字符串文件夹=args[0];
文件[]文件=(新文件(文件夹)).listFiles();
弦线;
对于(int i=0;i
对于某些java版本和某些文件打开时达到2035年的限制,存在一个错误。很可能你刚刚击中了那个
从评论中:
import java.util.*;
import java.io.*;
// if run with "java maxfiles 10000", will create 10k files in the current folder
public class maxfiles
{
static int count = 0;
static List files = new ArrayList();
public static void main(String args[]) throws Exception
{
for (int n = 0; n < Integer.parseInt(args[0]); n++) {
File f = new File("file" + count++);
//save ref, so not gc'ed
files.add(new PrintStream(new FileOutputStream(f)));
}
Iterator it = files.iterator();
while (it.hasNext()) {
PrintStream out = ( PrintStream) it.next();
out.println("foo");
out.flush();
}
System.out.println("current files open: " + files.size());
} //~main
}
为了澄清这个问题,在win32系统上,有三种方法可以打开
文件:
1:使用Win32 API
2:使用MFC类框架库
3:使用C库API(open()和fopen())
除了第三个选项,即选项1和选项2实际上没有
打开文件数量的限制。第三种方法受到限制
(原因我不知道)只打开大约2035个文件。那个
这就是为什么MS JVM能够打开无限(实际上)文件,而SUN
JVM在2035个文件之后失败(我猜它正在使用第三种方法
打开文件)
现在,这是一个很早以前就解决的老问题,但是他们可能会在网络访问上使用相同的功能,而错误可能仍然存在
即使不关闭句柄或流,windows也应该能够打开>10000个文件句柄并保持它们打开,如错误注释中的测试代码所示:
import java.util.*;
import java.io.*;
// if run with "java maxfiles 10000", will create 10k files in the current folder
public class maxfiles
{
static int count = 0;
static List files = new ArrayList();
public static void main(String args[]) throws Exception
{
for (int n = 0; n < Integer.parseInt(args[0]); n++) {
File f = new File("file" + count++);
//save ref, so not gc'ed
files.add(new PrintStream(new FileOutputStream(f)));
}
Iterator it = files.iterator();
while (it.hasNext()) {
PrintStream out = ( PrintStream) it.next();
out.println("foo");
out.flush();
}
System.out.println("current files open: " + files.size());
} //~main
}
import java.util.*;
导入java.io.*;
//如果使用“java maxfiles 10000”运行,将在当前文件夹中创建10k文件
公共类maxfile
{
静态整数计数=0;
静态列表文件=新的ArrayList();
公共静态void main(字符串args[])引发异常
{
for(int n=0;n
您可以在网络共享上测试运行它,如果失败,则报告错误。您也可以尝试使用不同的JDK。至少在source中,除了WinAPI调用之外,我看不到任何其他调用,所以我会尝试是否行为相同。我不会仅仅丢弃异常并将连接保持在未知状态,而是添加try/catch/最后确保关闭所有打开的连接。在循环中,您应该关闭所有资源。我认为您正在让FileReader保持打开状态,因为您只是在关闭BufferedReader。。。您应该尝试最终捕获并最终关闭这些资源。@chrislhardin认为这不是真的。很好的任务,imho。如果将调用更改为
File[]files=(新文件(文件夹)).listFiles(),会发生什么
toString[]files=(新文件(文件夹)).list()代码>?它解决了你的问题吗?@Serg你能添加你的windows版本+java版本吗它不会编译,正如你在try BlockWrite中定义的br
,没有编译检查,我相信OP get是关键。另外,我打赌新的java 7文件API可能会执行得更好。@eis,实际上正如你在代码中看到的,我不会同时打开多个文件(我也不希望)。由于某种原因,我收到了错误,就好像我收到了一样。我怀疑close()
会在线程实际关闭文件之前释放线程,因此new BufferedReader()
会在关闭最后一个文件之前开始。@Serg它是否同时运行可能并不重要。但是我建议您测试a)不同的JDK和b)在一个单独的方法上读取,将文件名作为一个参数,这样您就可以隔离它是否是一个gc问题(如果只在一个单独的方法中定义读取器,JVM更容易执行gc)
import java.util.*;
import java.io.*;
// if run with "java maxfiles 10000", will create 10k files in the current folder
public class maxfiles
{
static int count = 0;
static List files = new ArrayList();
public static void main(String args[]) throws Exception
{
for (int n = 0; n < Integer.parseInt(args[0]); n++) {
File f = new File("file" + count++);
//save ref, so not gc'ed
files.add(new PrintStream(new FileOutputStream(f)));
}
Iterator it = files.iterator();
while (it.hasNext()) {
PrintStream out = ( PrintStream) it.next();
out.println("foo");
out.flush();
}
System.out.println("current files open: " + files.size());
} //~main
}