如何读取指定目录所有文件并合并内容至单个文件?能否用Files.walk实现?
读取指定目录所有文件并合并内容的实现方案
核心结论
完全可以使用Files.walk实现该需求,它能递归遍历目录下所有文件(含子目录),配合Java流操作可高效完成文件内容合并。
完整实现代码
结合你已创建的目录结构,以下是可直接运行的完整代码:
import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.stream.Stream; public class FileMergeExample { public static void main(String[] args) { // 初始化目录与文件(你的原有代码) Path pathDir = Path.of("files_STREAM_Lesson7"); if (!Files.exists(pathDir)) { try { Files.createDirectory(pathDir); } catch (IOException e) { e.printStackTrace(); } } Path pathDir1 = Path.of("files_STREAM_Lesson7/newDIR"); if (!Files.exists(pathDir1)) { try { Files.createDirectory(pathDir1); } catch (IOException e) { e.printStackTrace(); } } Path pathFile1 = Path.of("files_STREAM_Lesson7/Lesson7NIO1.txt"); if (!Files.exists(pathFile1)) { try { Files.createFile(pathFile1); // 写入测试内容 Files.writeString(pathFile1, "这是Lesson7NIO1的内容\n", StandardCharsets.UTF_8); } catch (IOException e) { e.printStackTrace(); } } Path pathFile2 = Path.of("files_STREAM_Lesson7/newDIR/Lesson7NIO2.txt"); if (!Files.exists(pathFile2)) { try { Files.createFile(pathFile2); Files.writeString(pathFile2, "这是Lesson7NIO2的内容\n", StandardCharsets.UTF_8); } catch (IOException e) { e.printStackTrace(); } } Path pathFile3 = Path.of("files_STREAM_Lesson7/newDIR/Lesson7NIO3.txt"); if (!Files.exists(pathFile3)) { try { Files.createFile(pathFile3); Files.writeString(pathFile3, "这是Lesson7NIO3的内容\n", StandardCharsets.UTF_8); } catch (IOException e) { e.printStackTrace(); } } Path rootPath = Paths.get("files_STREAM_Lesson7"); // 合并结果文件路径 Path mergedFile = Path.of("files_STREAM_Lesson7/merged_result.txt"); try (Stream<Path> fileStream = Files.walk(rootPath)) { fileStream.filter(Files::isRegularFile) // 排除合并文件本身,避免循环写入 .filter(path -> !path.equals(mergedFile)) // 将每个文件的内容行展开为连续流 .flatMap(path -> { try { return Files.lines(path, StandardCharsets.UTF_8); } catch (IOException e) { e.printStackTrace(); return Stream.empty(); } }) // 追加写入到合并文件 .forEach(line -> { try { Files.writeString(mergedFile, line + "\n", StandardCharsets.UTF_8, java.nio.file.StandardOpenOption.CREATE, java.nio.file.StandardOpenOption.APPEND); } catch (IOException e) { e.printStackTrace(); } }); System.out.println("文件合并完成,结果路径:" + mergedFile.toAbsolutePath()); } catch (IOException e) { e.printStackTrace(); } } }
关键代码解析
Files.walk(rootPath):递归遍历目标目录下的所有路径,返回Stream<Path>,需用try-with-resources自动关闭流避免资源泄漏。filter(Files::isRegularFile):仅保留普通文件,过滤掉目录。flatMap(Files::lines):将每个文件的内容行展开为单一Stream<String>,替代你尝试的map(Files::readAllLines)(后者返回Stream<List<String>>,需额外处理嵌套集合)。StandardOpenOption.APPEND:指定写入模式为追加,避免覆盖已有内容;CREATE选项确保文件不存在时自动创建。
注意事项
- 异常处理:所有IO操作必须捕获
IOException,防止程序意外崩溃。 - 字符编码:明确指定编码(如
UTF_8),避免跨系统的编码兼容问题。 - 循环写入规避:过滤掉合并结果文件本身,防止将合并后的内容再次写入自身。
内容的提问来源于stack exchange,提问作者R Zav
相关产品推荐
相关产品推荐

