Yanıtlar:
File#isDirectory()Verilen dosyanın (yol) bir dizin olup olmadığını test etmek için kullanabilirsiniz . Eğer trueöyleyse, o zaman File#listFiles()sonucu ile aynı yöntemi tekrar çağırırsınız . Buna özyineleme denir .
İşte temel bir başlama örneği.
public static void main(String... args) {
File[] files = new File("C:/").listFiles();
showFiles(files);
}
public static void showFiles(File[] files) {
for (File file : files) {
if (file.isDirectory()) {
System.out.println("Directory: " + file.getName());
showFiles(file.listFiles()); // Calls same method again.
} else {
System.out.println("File: " + file.getName());
}
}
}
Bunun, StackOverflowErrorağaç JVM'nin yığınının tutabileceğinden daha derin olduğunda hassas olduğunu unutmayın . Bunun yerine yinelemeli bir yaklaşım veya kuyruk özyineleme kullanmak isteyebilirsiniz , ancak bu başka bir konudur;)
NullPointerExceptiondosya sistemi çağrı arasında değiştiğinde isDirectoryve bloklar veya gerçekten şanssız olursanız listFilesolabileceği gibi bir zamana karşı hassastır System.out.println. Çıktının listFilesboş olup olmadığını kontrol etmek o yarış koşulunu çözecektir.
java.nio.file.DirectoryStreambir dizin üzerinde yinelenmenize izin verir ve küçük bir bellek ayak izine sahip olmak için uygulanabilir, ancak kesin olarak söylemenin tek yolu belirli bir platformda bellek kullanımını izlemek için.
Java 1.7 kullanıyorsanız, java.nio.file.Files.walkFileTree(...) .
Örneğin:
public class WalkFileTreeExample {
public static void main(String[] args) {
Path p = Paths.get("/usr");
FileVisitor<Path> fv = new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
System.out.println(file);
return FileVisitResult.CONTINUE;
}
};
try {
Files.walkFileTree(p, fv);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Java 8 kullanıyorsanız akış arayüzünü aşağıdakilerle birlikte kullanabilirsiniz java.nio.file.Files.walk(...):
public class WalkFileTreeExample {
public static void main(String[] args) {
try (Stream<Path> paths = Files.walk(Paths.get("/usr"))) {
paths.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Check out FileUtils Apache Commons sınıfı - özellikle iterateFiles :
Belirli bir dizindeki (ve isteğe bağlı olarak alt dizinlerindeki) dosyalar üzerinde yinelemeye izin verir.
Java 7+ için ayrıca https://docs.oracle.com/javase/7/docs/api/java/nio/file/DirectoryStream.html var
Javadoc'tan alınan örnek:
List<Path> listSourceFiles(Path dir) throws IOException {
List<Path> result = new ArrayList<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{c,h,cpp,hpp,java}")) {
for (Path entry: stream) {
result.add(entry);
}
} catch (DirectoryIteratorException ex) {
// I/O error encounted during the iteration, the cause is an IOException
throw ex.getCause();
}
return result;
}
Belirtildiği gibi, bu bir özyineleme problemidir. Özellikle,
listFiles()
Java Dosya API olarak burada . Bir dizindeki tüm dosyaların bir dizisini döndürür. İle birlikte kullanma
isDirectory()
daha fazla bilgi almanız gerekip gerekmediğini görmek iyi bir başlangıçtır.
@Msandiford yanıtı ile eklemek için, çoğu zaman bir dosya ağacının yürüdüğü zaman, bir işlevi bir dizin olarak yürütmek veya belirli bir dosya ziyaret etmek isteyebilirsiniz. Eğer u akışları kullanmak konusunda isteksizseniz. Geçersiz kılınan aşağıdaki yöntemler uygulanabilir
Files.walkFileTree(Paths.get(Krawl.INDEXPATH), EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
// Do someting before directory visit
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
// Do something when a file is visited
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc)
throws IOException {
// Do Something after directory visit
return FileVisitResult.CONTINUE;
}
});
Ayrıca, dosya geçişi için File.list'i (Dosyaadı Filtresi) (ve varyantlarını) kötüye kullanabilirsiniz. Kısa kod ve erken java sürümlerinde çalışır, örneğin:
// list files in dir
new File(dir).list(new FilenameFilter() {
public boolean accept(File dir, String name) {
String file = dir.getAbsolutePath() + File.separator + name;
System.out.println(file);
return false;
}
});