Вступление
Многие приложения тем или иным образом обрабатывают файлы, и манипулирование файлами - одно из основных знаний любого языка программирования.
Чтобы управлять файлами, нам нужно знать, где они находятся. Обзор файлов в каталоге имеет первостепенное значение, если мы хотим этого добиться, особенно если мы можем выполнять над ними операции посредством итераций. В Java есть несколько способов сделать это, которые мы покажем в этой статье.
Для простоты все примеры будут написаны для следующего дерева файлов:
Programming
|-- minimax.c
|-- super_hack.py
|-- TODO.txt
`-- CodingMusic
|-- Girl Talk - All Day.mp3
|-- Celldweller - Frozen.mp3
|-- Lim Taylor - Isn't It Wonderful.mp3
`-- Radiohead - Everything in Its Right Place.mp3
File.list ()
Самый простой метод для перечисления имен файлов и папок в данном
каталоге без обхода подкаталогов - это вспомогательный метод .list()
,
который возвращает массив String
s.
Мы делаем это с помощью .list()
File
экземпляра File:
public class Pathnames {
public static void main(String[] args) {
// Creates an array in which we will store the names of files and directories
String[] pathnames;
// Creates a new File instance by converting the given pathname string
// into an abstract pathname
File f = new File("D:/Programming");
// Populates the array with names of files and directories
pathnames = f.list();
// For each pathname in the pathnames array
for (String pathname : pathnames) {
// Print the names of files and directories
System.out.println(pathname);
}
}
}
Используя простой цикл
for-each , мы перебираем
массив и распечатываем String
s.
CodingMusic
minimax.c
super_hack.py
TODO.txt
При использовании этого подхода все элементы в CodingMusic
не
отображаются, а обратная сторона этого подхода заключается в том, что мы
не можем ничего сделать с самими файлами. Мы просто получаем их имена.
Это полезно, когда мы просто хотим взглянуть на файлы по номинальной
стоимости.
FilenameFilter
Еще одна вещь, которую мы можем сделать с помощью .list()
- это
создать FilenameFilter
чтобы возвращать только те файлы, которые нам
нужны:
File f = new File("D:/Programming");
// This filter will only include files ending with .py
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File f, String name) {
return name.endsWith(".py");
}
};
// This is how to apply the filter
pathnames = f.list(filter);
Выполнение этого фрагмента кода даст:
super_hack.py
File.listFiles ()
Подобно предыдущему методу, этот можно использовать для возврата имен
файлов и каталогов, но на этот раз мы получаем их как массив File
,
что дает нам возможность напрямую ими манипулировать:
public class Pathnames {
public static void main(String args[]) {
// try-catch block to handle exceptions
try {
File f = new File("D:/Programming");
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File f, String name) {
// We want to find only .c files
return name.endsWith(".c");
}
};
// Note that this time we are using a File class as an array,
// instead of String
File[] files = f.listFiles(filter);
// Get the names of the files by using the .getName() method
for (int i = 0; i < files.length; i++) {
System.out.println(files[i].getName());
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
Выход:
minimax.c
Теперь давайте углубимся в файловую систему, используя рекурсию и еще
несколько методов для использования с объектом File
public class ListFilesRecursively {
public void listFiles(String startDir) {
File dir = new File(startDir);
File[] files = dir.listFiles();
if (files != null && files.length > 0) {
for (File file : files) {
// Check if the file is a directory
if (file.isDirectory()) {
// We will not print the directory name, just use it as a new
// starting point to list files from
listDirectory(file.getAbsolutePath());
} else {
// We can use .length() to get the file size
System.out.println(file.getName() + " (size in bytes: " + file.length()+")");
}
}
}
}
public static void main(String[] args) {
ListFilesRecursively test = new ListFilesRecursively();
String startDir = ("D:/Programming");
test.listFiles(startDir);
}
}
Выход:
Girl Talk - All Day.mp3 (size in bytes: 8017524)
Celldweller - Frozen.mp3 (size in bytes: 12651325)
Lim Taylor - Isn't It Wonderful.mp3 (size in bytes: 6352489)
Radiohead - Everything in Its Right Place.mp3 (size in bytes: 170876098)
minimax.c (size in bytes: 20662)
super_hack.py (size in bytes: 114401)
TODO.txt (size in bytes: 998)
Files.walk ()
В Java 8 и более поздних версиях мы можем использовать
java.nio.file.Files
для заполнения Stream
и использовать его для
просмотра файлов и каталогов и в то же время рекурсивно просматривать
все подкаталоги.
Обратите внимание, что в этом примере мы будем использовать лямбда-выражения :
public class FilesWalk {
public static void main(String[] args) {
try (Stream<Path> walk = Files.walk(Paths.get("D:/Programming"))) {
// We want to find only regular files
List<String> result = walk.filter(Files::isRegularFile)
.map(x -> x.toString()).collect(Collectors.toList());
result.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Здесь мы заполнили Stream
с помощью .walk()
, передав аргумент
Paths
Класс Paths
состоит из статических методов, которые возвращают
Path
на основе строкового URI - и, используя Path
, мы можем легко
найти файл.
Path
, Paths
, Files
и многие другие классы принадлежат java.nio
, который был представлен в Java 7 как более современный способ
представления файлов неблокирующим образом.
Затем с помощью Collections Framework создается список.
Выполнение этого фрагмента кода даст:
D:\Programming\Coding Music\Radiohead - Everything in Its Right Place.mp3
D:\Programming\Coding Music\Lim Taylor - Isn't It Wonderful.mp3
D:\Programming\Coding Music\Celldweller - Frozen.mp3
D:\Programming\Coding Music\Girl Talk - All Day.mp3
D:\Programming\minimax.c
D:\Programming\super_hack.py
D:\Programming\TODO.txt
Заключение
Обработка файлов каким-либо образом является основной задачей для большинства языков программирования, и это включает в себя возможность просматривать и находить файлы в файловой системе. Чтобы управлять файлами, нам нужно знать, где они находятся. Обзор файлов в каталоге имеет первостепенное значение, если мы хотим этого добиться, особенно если мы можем выполнять над ними операции посредством итераций.
В этой статье мы показали несколько различных способов в Java перечислить файлы в файловой системе, используя как линейный, так и рекурсивный подходы.