遍历文件路径读取内容时,如何为每个文件生成独立日志文件
实现按文件生成独立日志文件(基于Log4j2)
一、添加Maven依赖
先在pom.xml中引入Log4j2核心依赖,已有文件处理相关依赖(如Apache POI、PDFBox等)可保留:
<dependencies> <!-- Log4j2核心依赖 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.20.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.20.0</version> </dependency> </dependencies>
二、动态创建Logger工具类
因为要为每个文件生成独立日志,不能用静态Logger,需根据文件名动态生成Logger和对应文件输出Appender,同时做缓存避免重复创建:
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.Appender; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.appender.FileAppender; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.layout.PatternLayout; import java.io.File; import java.util.HashMap; import java.util.Map; public class FileLoggerUtil { private static final Map<String, Logger> LOGGER_CACHE = new HashMap<>(); public static Logger getFileLogger(File targetFile) { // 拆分文件名和扩展名,生成日志文件前缀 String fileName = targetFile.getName(); String namePrefix = fileName.substring(0, fileName.lastIndexOf('.')); String ext = fileName.substring(fileName.lastIndexOf('.') + 1); String loggerKey = String.format("%s_%s", namePrefix, ext); String logFilePath = new File(targetFile.getParent(), loggerKey + ".log").getAbsolutePath(); // 缓存命中直接返回 if (LOGGER_CACHE.containsKey(loggerKey)) { return LOGGER_CACHE.get(loggerKey); } // 初始化Log4j2配置 LoggerContext context = (LoggerContext) LogManager.getContext(false); Configuration config = context.getConfiguration(); // 定义日志输出格式 PatternLayout layout = PatternLayout.newBuilder() .withPattern("%d{yyyy-MM-dd HH:mm:ss} [%level] %msg%n") .withConfiguration(config) .build(); // 创建文件输出Appender Appender fileAppender = FileAppender.newBuilder() .setName(loggerKey + "_Appender") .setFileName(logFilePath) .setLayout(layout) .setConfiguration(config) .build(); fileAppender.start(); config.addAppender(fileAppender); // 创建并配置Logger org.apache.logging.log4j.core.Logger logger = (org.apache.logging.log4j.core.Logger) LogManager.getLogger(loggerKey); logger.addAppender(fileAppender); logger.setLevel(org.apache.logging.log4j.Level.INFO); logger.setAdditivity(false); // 禁止日志转发到根Logger LOGGER_CACHE.put(loggerKey, logger); return logger; } }
三、整合到现有文件处理逻辑
在遍历文件夹读取文件的代码中,调用工具类获取对应Logger,输出文件相关信息:
import org.apache.logging.log4j.Logger; import java.io.File; import java.util.Arrays; import java.util.HashSet; import java.util.Set; public class FolderProcessor { // 支持的文件类型集合,根据实际读取逻辑调整 private static final Set<String> SUPPORTED_EXTENSIONS = new HashSet<>(Arrays.asList( "txt", "pdf", "docx", "doc", "xlsx", "xls", "csv", "xml", "log" )); public static void main(String[] args) { if (args.length == 0) { System.err.println("请传入目标文件夹路径"); return; } processFolder(args[0]); } public static void processFolder(String folderPath) { File folder = new File(folderPath); if (!folder.isDirectory()) { System.err.println("指定路径不是有效文件夹"); return; } File[] targetFiles = folder.listFiles((dir, name) -> { int dotIdx = name.lastIndexOf('.'); if (dotIdx == -1) return false; String ext = name.substring(dotIdx + 1).toLowerCase(); return SUPPORTED_EXTENSIONS.contains(ext); }); if (targetFiles == null || targetFiles.length == 0) { System.err.println("文件夹中无支持的文件类型"); return; } for (File file : targetFiles) { Logger fileLogger = FileLoggerUtil.getFileLogger(file); // 调用你已实现的文件读取方法 String content = readFileContent(file); // 输出日志,可根据需求添加更多信息 fileLogger.info("文件路径:{}", file.getAbsolutePath()); fileLogger.info("文件大小:{} bytes", file.length()); fileLogger.info("文件内容:\n{}", content); } } // 你的文件读取实现,处理不同类型文件 private static String readFileContent(File file) { // 替换成你已有的读取逻辑 return "模拟读取的文件内容"; } }
四、关键注意点
- 缓存机制:用Map缓存Logger实例,避免重复创建Appender,提升批量处理性能。
- 日志路径:默认和原文件同目录,如需统一输出到指定目录,修改
logFilePath的生成逻辑即可。 - 类型匹配:确保
SUPPORTED_EXTENSIONS包含所有实际处理的文件扩展名(如.doc和.docx都需添加)。 - Log4j2版本:选择稳定版本,避免依赖冲突。
内容的提问来源于stack exchange,提问作者Seriously
相关产品推荐
相关产品推荐

