Недавно мне нужно было прочитать целую кучу файлов, и вместо того, чтобы просто взять мой старый FileUtils.java, который есть у меня и, вероятно, у большинства разработчиков, а затем скопировать из проекта в проект, я решил быстро взглянуть на то, как еще это сделать…
Да, я знаю, что есть Commons IO и Google IO , зачем мне вообще беспокоиться? Они, вероятно, делают это лучше, но я хотел проверить классы NIO jdk и поиграть с лямбдами… и, честно говоря, я думаю, что на самом деле это был очень аккуратный кусок кода.
Итак, у меня был конкретный вариант использования:
Я хотел прочитать все исходные файлы из целого дерева каталогов, построчно.
Что делает этот код, он использует Files.walk для рекурсивного получения всех путей из начальной точки, он создает поток, который я затем фильтрую только для файлов, которые заканчиваются требуемым расширением. Для каждого из этих файлов я использую Files.lines для создания потока строк, по одному на строку. Я обрежу это, отфильтрую пустые и добавлю их в коллекцию возврата.
Все очень лаконично благодаря новым конструкциям.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
package net.briandupreez.blog.java8.io;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import java.io.IOException;import java.nio.charset.Charset;import java.nio.file.FileVisitOption;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.util.ArrayList;import java.util.List;import java.util.stream.Stream;/** * RecursiveFileLineReader * Created by Brian on 2014-05-26. */public class RecursiveFileLineReader { private transient static final Log LOG = LogFactory.getLog(RecursiveFileLineReader.class); /** * Get all the non empty lines from all the files with the specific extension, recursively. * * @param path the path to start recursion * @param extension the file extension * @return list of lines */ public static List<String> readAllLineFromAllFilesRecursively(final String path, final String extension) { final List<String> lines = new ArrayList<>(); try (final Stream<Path> pathStream = Files.walk(Paths.get(path), FileVisitOption.FOLLOW_LINKS)) { pathStream .filter((p) -> !p.toFile().isDirectory() && p.toFile().getAbsolutePath().endsWith(extension)) .forEach(p -> fileLinesToList(p, lines)); } catch (final IOException e) { LOG.error(e.getMessage(), e); } return lines; } private static void fileLinesToList(final Path file, final List<String> lines) { try (Stream<String> stream = Files.lines(file, Charset.defaultCharset())) { stream .map(String::trim) .filter(s -> !s.isEmpty()) .forEach(lines::add); } catch (final IOException e) { LOG.error(e.getMessage(), e); } }} |
| Ссылка: | Игра с Java 8 — лямбды, пути и файлы от нашего партнера по JCG Брайана Дю Приза в блоге Zen в искусстве ИТ . |