Ich habe (in Java) einen ziemlich direkten Iterator implementiert, um die Namen der Dateien in einer rekursiven Verzeichnisstruktur zurückzugeben, und nach etwa 2300 Dateien fehlgeschlagen "Zu viele offene Dateien im System" (der Fehler war eigentlich der Versuch, eine Klasse zu laden, aber ich nehme an, dass die Verzeichnisliste der Schuldige war)."Zu viele geöffnete Dateien im System" Fehler beim Auflisten einer rekursiven Verzeichnisstruktur
Die vom Iterator verwaltete Datenstruktur ist ein Stack, der den Inhalt der Verzeichnisse enthält, die auf jeder Ebene geöffnet sind.
Die eigentliche Logik ist recht einfach:
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);
}
}
}
}
Ich verstehe möchte, wie viele „offene Dateien“ dies erfordert. Unter welchen Umständen öffnet dieser Algorithmus eine Datei und wann wird sie wieder geschlossen?
Ich habe einige nette Code mit Hilfe von Java 7 oder Java 8, gesehen, aber ich bin auf Java 6.
einfach Ihren Code mit mehr als 1.000.000 Dateien auf einem Dateisystem lief, und habe nicht das Problem, das Sie sehen. Ich verwende JDK 1.6.0_34 unter Windows. Vielleicht ist das Problem an anderer Stelle im Code? Können Sie den Code für den 'FilenameFilter' posten, den Sie verwenden? Das könnte das Problem sein. – msandiford
Es kann sein, dass Ihr Dateisystem nicht so tief ist, sodass Ressourcen vom GC an das Betriebssystem zurückgegeben werden. Oder vielleicht hat Ihr Betriebssystem ein größeres Limit für geöffnete Dateien. –
Ja, ich lag letzte Nacht wach und fragte mich, ob der FileNameFilter dafür verantwortlich war. Aber nein: Die Methode accept() gibt 'neue Datei (dir, name) .isDirectory() || zurück pattern.matcher (name) .matches(); ' –