c.q.l.co.rolling.helper.RenameUtil - 无法在Windows上重命名文件

时间:2016-08-20 18:27:37

标签: java logback file-rename

我正在使用带有SizeAndTimeBasedFNATP的logback RollingFileAppender。一切看起来都不错,而不是翻滚。代码是:

MultiDex.install(Context)

当我在调试模式下运行相同的程序时,我发现File类中的renameTo方法失败,返回false而没有任何错误消息。我在Windows 10上运行我的程序。我使用processMonitor(Procman.exe)进行双/三检查以捕获任何持有该文件的进程(application.log)。没有进程持有该文件。以下输出仍然失败。如何解决这个问题?

package com.rsa.springclasses.day3.logback;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Properties;

import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.ConsoleAppender;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP;
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
import ch.qos.logback.core.status.OnConsoleStatusListener;
import ch.qos.logback.core.status.StatusManager;

@Configuration
@ComponentScan
public class AppConfig {
  @Bean
  public LoggerContext getLoggerContext() {
    LoggerContext lctx = this.initLoggerContext();
    return lctx;
  }

  public LoggerContext initLoggerContext() {
    LoggerContext lctx = (LoggerContext) LoggerFactory.getILoggerFactory();
    lctx.setName("ApplicationLogger");
    lctx.reset();

    StatusManager sm = lctx.getStatusManager();
    OnConsoleStatusListener ocsl = new OnConsoleStatusListener();
    sm.add(ocsl);
    ocsl.start();

    Properties lp = readLogbackProperties();

    PatternLayoutEncoder cple = this.getPatternEncoder(lp);
    cple.setContext(lctx);
    //cple.stop();
    cple.start();
    System.out.println("Console logging pattern used: " + cple.getPattern());

    // Appenders
    ConsoleAppender<ILoggingEvent> capp = this.getConsoleAppender();
    capp.setContext(lctx);
    capp.setEncoder(cple);
    //capp.stop();
    capp.start();
    System.out.println("Console appender started...");

    PatternLayoutEncoder fple = this.getPatternEncoder(lp);
    fple.setContext(lctx);
    //fple.stop();
    fple.start();
    System.out.println("File logging pattern used: " + fple.getPattern());

    RollingFileAppender<ILoggingEvent> rfapp = this.getRollingFileAdapter(lctx, fple, lp);
    //rfapp.stop();
    rfapp.start();

    Logger rootLogger = lctx.getLogger(Logger.ROOT_LOGGER_NAME);
    //lctx.stop();

    rootLogger.detachAndStopAllAppenders();
    rootLogger.addAppender(rfapp);
    rootLogger.addAppender(capp);

    this.setLoggerLevels(lctx, lp);
    for (Logger l : lctx.getLoggerList()) {
        System.out.println("Logger name: " + l.getName() + ", Log Level: " + l.getLevel());
    }

    lctx.start();
    rootLogger.debug("Logger context created.");

    Iterator<Appender<ILoggingEvent>> apps = rootLogger.iteratorForAppenders();
    while(apps.hasNext()) {
        Appender<ILoggingEvent> app = apps.next();
        System.out.println("Appenders available: " + app.getName());
    }

    return lctx;
  }

  public RollingFileAppender<ILoggingEvent> getRollingFileAdapter(LoggerContext lctx, PatternLayoutEncoder ple, Properties lp) {
    File logsdir = this.getLogDir(lp);
    String logsFileName = "application.log";
    if (lp.getProperty("FILE_NAME") != null) {
        logsFileName = lp.getProperty("FILE_NAME");
    }
    String logsRollPattern = "application.%d{yyyy-MMM-dd_HH:mm:ss}.log";
    if (lp.getProperty("ROLL_FILE_NAME_PATTERN") != null) {
        logsRollPattern = lp.getProperty("ROLL_FILE_NAME_PATTERN");
    }
    System.out.println("File rolling pattern used: " + logsRollPattern);
    RollingFileAppender<ILoggingEvent> appender = new RollingFileAppender<ILoggingEvent>();
    appender.setName("ApplicationRollingFileAppender");
    appender.setFile(logsdir.getAbsolutePath().replaceAll("\\\\", "/") + "/" + logsFileName);
    appender.setContext(lctx);
    appender.setEncoder(ple);
    appender.setAppend(true);

    SizeAndTimeBasedFNATP<ILoggingEvent> stbf = new SizeAndTimeBasedFNATP<>();
    stbf.setContext(lctx);
    stbf.setMaxFileSize("2KB");

    TimeBasedRollingPolicy<ILoggingEvent> rollingPolicy = new TimeBasedRollingPolicy<>();
    rollingPolicy.setContext(lctx);
    rollingPolicy.setParent(appender);
    rollingPolicy.setFileNamePattern(logsdir.getAbsolutePath().replaceAll("\\\\", "/") + "/" + logsRollPattern);
    rollingPolicy.setMaxHistory(30);
    rollingPolicy.setTimeBasedFileNamingAndTriggeringPolicy(stbf);

    stbf.setTimeBasedRollingPolicy(rollingPolicy);
    //rollingPolicy.stop();
    rollingPolicy.start();
    stbf.start();

    appender.setRollingPolicy(rollingPolicy);

    return appender;
  }

  public ConsoleAppender<ILoggingEvent> getConsoleAppender() {
    ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<ILoggingEvent>();
    appender.setName("ApplicationConsoleAppender");
    return appender;
  }

  public PatternLayoutEncoder getPatternEncoder(Properties props) {
    if (props == null) {
        props = this.readLogbackProperties();
    }
    String pattern = "%msg%n";
    if (props.containsKey("PATTERN")) {
        pattern = props.getProperty("PATTERN");
    }
    PatternLayoutEncoder ple = new PatternLayoutEncoder();
    ple.setPattern(pattern);
    return ple;
  }

  public void setLoggerLevels(LoggerContext lctx, Properties props) {
    if (props == null) {
        props = this.readLogbackProperties();
    }
    for(String lname: props.stringPropertyNames()) {
        if (lname.startsWith("SET_LOGBACK_LEVEL_")) {
            String level = props.getProperty(lname);
            String pname = lname.substring(18);
            lctx.getLogger(pname).setLevel(Level.valueOf(level));
        }
    }
  }

  public File getLogDir(Properties lp) {
    if (lp == null) {
        lp = this.readLogbackProperties();
    }
    if (lp.getProperty("LOGSDIR") == null) {
        throw new IllegalArgumentException("LOGSDIR property not found in logback.properties");
    }
    File logsdir = new File(lp.getProperty("LOGSDIR"));
    if (logsdir.exists()) {
        System.out.println("Directory already available: " + logsdir.getAbsolutePath());
    } else {
        logsdir.mkdirs();
        System.out.println("Directory created: " + logsdir.getAbsolutePath());
    }
    return logsdir;
  }

  public Properties readLogbackProperties() {
    ClassPathResource cpr = new ClassPathResource("day3/logback/logback.properties");
    System.out.println("File used to load the logback properties: " + cpr.getPath());
    Properties p = new Properties();
    try {
        p.load(cpr.getInputStream());
    } catch (IOException e) {
        throw new IllegalArgumentException("Failed to find day3/logback/logback.properties in classpath. " + e.getMessage());
    } catch (IllegalArgumentException iae) {
        throw new IllegalArgumentException("Failed to read day3/logback/logback.properties in classpath. File might contain a malformed Unicode escape sequence. " + iae.getMessage());
    }
    return p;
  }
}

1 个答案:

答案 0 :(得分:0)

我将滚动模式更改为application_%d {yyyy-MMM-dd_HH_mm_ss} _%i.log,然后文件重命名开始工作。愚蠢的错误。基本上,Windows不接受文件名中的“:”。如果Java File.renameTo在这种情况下抛出一些错误消息而不是返回false,那将是非常好的。