我最近需要读取一堆文件,而不是仅仅抓住我和可能是大多数开发人员拥有的旧FileUtils.java,然后从一个项目复制到另一个项目,我决定快速了解其他方法。
是的,我知道有Commons IO和Google IO ,我为什么还要打扰? 他们可能会做得更好,但是我想检查一下NIO jdk类并同时使用lambda。而且,老实说,我认为这实际上是一段非常整齐的代码。
所以我有一个特定的用例:
我想逐行从整个目录树中读取所有源文件。
该代码的作用是,它使用Files.walk从起点递归获取所有路径,并创建一个流,然后将其过滤为仅以所需扩展名结尾的文件。 对于每个文件,我使用Files.lines创建一个字符串流,每行一个。 我修剪一下,过滤掉空的并将其添加到return集合中。
一切都非常简洁,这要归功于新的构造。
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);
}
}
}
翻译自: https://www.javacodegeeks.com/2014/05/playing-with-java-8-lambdas-paths-and-files.html