Java Windows环境下更新properties文件路径异常排查
问题定位与解决:Log4j配置文件路径转义导致日志文件未生成
问题现象
通过Java代码更新log4j.properties的日志路径后,配置文件中路径出现C\:/格式的转义字符,日志文件夹已成功创建但目标日志文件未生成。
执行代码
private void updateLog4jProperties(String operationName) { FileInputStream in; try { in = new FileInputStream("config/log4j.properties"); Properties props = new Properties(); props.load(in); in.close(); FileOutputStream out = new FileOutputStream("config/log4j.properties"); if (System.getProperty("os.name").toLowerCase().indexOf("windows") >= 0) { props.setProperty("log", "C:/temp/logs/myapp"); Files.createDirectories(Paths.get("C:/temp/logs/myapp")); } else { props.setProperty("log", "/var/tmp/logs/myapp"); Files.createDirectories(Paths.get("/var/tmp/logs/myapp")); } props.setProperty("log4j.appender.FILE.File", props.getProperty("log") + "/" + "myapp_" + operationName + "_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".log"); props.store(out, null); out.close(); } catch (IOException e) { e.printStackTrace(); } }
生成的log4j.properties内容
#Thu Mar 02 17:24:46 IST 2023 log4j.rootLogger=DEBUG, FILE log4j.appender.FILE.File=C\:/temp/logs/myapp/myapp_Test_20230302172446.log log4j.appender.FILE=org.apache.log4j.FileAppender log4j.appender.FILE.layout=org.apache.log4j.PatternLayout log4j.appender.FILE.layout.conversionPattern=%d{HH\:mm\:ss.SSS} %-5level %logger{36} - %msg%n log=C\:/temp/logs/myapp
问题原因
Java的Properties.store()方法会自动对冒号(:)、等号(=)等特殊字符添加反斜杠转义。而Log4j 1.x解析路径时,会将转义后的\:视为路径的一部分,导致实际解析的路径为C\:/temp/logs/myapp/...——这在Windows系统中是无效路径,因此无法创建日志文件。
解决方案
修改路径格式为Windows原生反斜杠
将Windows下的路径改为双反斜杠(Java字符串中需用\\表示单个反斜杠),Properties.store()处理后会输出单个反斜杠,Log4j能正确识别路径。
修改后的代码:
private void updateLog4jProperties(String operationName) { // 使用try-with-resources自动管理流,避免资源泄漏 try (FileInputStream in = new FileInputStream("config/log4j.properties"); FileOutputStream out = new FileOutputStream("config/log4j.properties")) { Properties props = new Properties(); props.load(in); String logDir; if (System.getProperty("os.name").toLowerCase().contains("windows")) { logDir = "C:\\temp\\logs\\myapp"; Files.createDirectories(Paths.get(logDir)); } else { logDir = "/var/tmp/logs/myapp"; Files.createDirectories(Paths.get(logDir)); } String logFilePath = logDir + "\\" + "myapp_" + operationName + "_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".log"; props.setProperty("log", logDir); props.setProperty("log4j.appender.FILE.File", logFilePath); props.store(out, null); } catch (IOException e) { e.printStackTrace(); } }
验证效果
修改后生成的log4j.properties中路径会变为:
log4j.appender.FILE.File=C:\temp\logs\myapp\myapp_Test_20230302172446.log log=C:\temp\logs\myapp
此时Log4j能正确解析路径,日志文件会正常生成到目标文件夹中。
额外优化建议
- 使用
try-with-resources语法自动关闭流,避免手动关闭时可能出现的资源泄漏问题。 - 用
java.time包下的DateTimeFormatter替代过时的SimpleDateFormat,提升线程安全性。
内容的提问来源于stack exchange,提问作者Ranjeet
相关产品推荐
相关产品推荐

