Tôi đã triển khai (trong Java) một Iterator khá đơn giản để trả về tên của tệp trong cấu trúc thư mục đệ quy và sau khoảng 2300 tệp không thành công "Quá nhiều tệp mở trong hệ thống" (sự cố thực sự đang cố gắng tải một lớp, nhưng tôi cho rằng danh sách thư mục là thủ phạm).Lỗi "Mở nhiều tệp trong hệ thống" khi liệt kê cấu trúc thư mục đệ quy
Cấu trúc dữ liệu được duy trì bởi trình lặp là một ngăn chứa nội dung của các thư mục được mở ở mỗi cấp.
Logic thực tế là khá cơ bản:
private static class DirectoryIterator implements Iterator<String> {
private Stack<File[]> directories;
private FilenameFilter filter;
private Stack<Integer> positions = new Stack<Integer>();
private boolean recurse;
private String next = null;
public DirectoryIterator(Stack<File[]> directories, boolean recurse, FilenameFilter filter) {
this.directories = directories;
this.recurse = recurse;
this.filter = filter;
positions.push(0);
advance();
}
public boolean hasNext() {
return next != null;
}
public String next() {
String s = next;
advance();
return s;
}
public void remove() {
throw new UnsupportedOperationException();
}
private void advance() {
if (directories.isEmpty()) {
next = null;
} else {
File[] files = directories.peek();
while (positions.peek() >= files.length) {
directories.pop();
positions.pop();
if (directories.isEmpty()) {
next = null;
return;
}
files = directories.peek();
}
File nextFile = files[positions.peek()];
if (nextFile.isDirectory()) {
int p = positions.pop() + 1;
positions.push(p);
if (recurse) {
directories.push(nextFile.listFiles(filter));
positions.push(0);
advance();
} else {
advance();
}
} else {
next = nextFile.toURI().toString();
count++;
if (count % 100 == 0) {
System.err.println(count + " " + next);
}
int p = positions.pop() + 1;
positions.push(p);
}
}
}
}
Tôi muốn hiểu có bao nhiêu "mở file" này đòi hỏi. Trong hoàn cảnh nào là thuật toán này "mở" một tập tin, và khi nào nó lại bị đóng lại?
Tôi đã nhìn thấy một số mã gọn gàng sử dụng Java 7 hoặc Java 8, nhưng tôi hạn chế đến Java 6.
Chỉ cần chạy mã của bạn trên một hệ thống tập tin với hơn 1.000.000 tập tin, và không nhận được vấn đề bạn đang nhìn thấy. Tôi đang sử dụng JDK 1.6.0_34 trên Windows. Có lẽ vấn đề là ở nơi khác trong mã? Bạn có thể đăng mã cho 'FilenameFilter' mà bạn đang sử dụng không? Đó có thể là vấn đề. – msandiford
Nó có thể là hệ thống tập tin của bạn không phải là sâu, do đó, các nguồn lực đang được trả lại cho hệ điều hành của GC. Hoặc có thể hệ điều hành của bạn có giới hạn lớn hơn đối với các tệp đang mở. –
Vâng, tôi nằm thức đêm qua tự hỏi liệu FileNameFilter có đổ lỗi hay không. Nhưng không: phương thức accept() thực hiện 'return new File (dir, name) .isDirectory() || pattern.matcher (name) .matches(); ' –