【问题标题】:Daily rollover for a FileOutputStream using Protocol Buffers?使用协议缓冲区的 FileOutputStream 的每日翻转?
【发布时间】:2014-09-26 12:29:26
【问题描述】:

我正在从服务器获取数据流(二进制格式)。此数据使用 Google 协议缓冲区进行序列化。我正在尝试进行每日翻转(即,如果第二天发生写入包含新日期的新文件,其中包含压缩数据)。

我尝试通过 log4j 来实现,但是,log4j 不考虑二进制(据我所知,我只能通过它获取文本)。当 log4j 写入文件时,它不会以二进制格式写入文件,而是以文本(人类可读)格式写入。

我通过这个问题在 log4j How to Create Binary Log File in Java using Log4J 中创建了一个自定义二进制附加程序

但是,我几天前才开始使用 log4j,我不太确定如何去做。

还有其他方法可以对二进制数据进行翻转吗?我什至不确定 log4j 是否是最好的解决方案。我非常乐意尝试您能提出的任何解决方案!

我希望 log4j 将数据写入二进制而不是文本。

有没有办法在java中对二进制文件进行每日翻转?

【问题讨论】:

  • 为什么不自己打开文件?
  • @talex 你是什么意思?
  • 只要打开 FileInputStream 并写下你想要的。半夜关上,再打开一个。
  • 您需要什么来保存从服务器获取的数据?只是为了备份?您需要将哪些元数据与来自服务器的数据一起存储?只是收到数据的时间?如果数据很重要,我可能希望将其存储在数据库中并为 ProtoBuff 数据使用 BLOB。如果您确定文本日志文件就足够了,我会将 ProtoBuff 数据编码为 ASCII 格式,例如 Base64,这样当您使用文本编辑器查看日志文件时,它将是可读的。
  • 是否可以将原始 protobuf 文本转换为序列化的 protobuf 二进制文件?

标签: java log4j protocol-buffers fileoutputstream


【解决方案1】:

我认为这里不需要 log4j。如果您只需要文件翻转小流包装器就足够了。

Jetty 项目在它的 util classes RolloverFileRotator 中实现了这样的 FileOuputStream,我认为这里非常适合。

【讨论】:

    【解决方案2】:

    您可以扩展默认 log4j DailyRollingFileAppender 并将其包含在您的类路径中

    package test.com;
    
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    import org.apache.log4j.DailyRollingFileAppender;
    import org.apache.log4j.spi.LoggingEvent;
    
    public class BinaryRollingFileAppender extends DailyRollingFileAppender {
    
        FileOutputStream fout;
    
        public BinaryRollingFileAppender(){
        }
    
        @Override
        public void setFile(String file) {
            super.setFile(file);
            try {
                fout = new FileOutputStream(file);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void append(LoggingEvent le) {
            try {
                fout.write((byte[])le.getMessage());
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    
        @Override
        public boolean requiresLayout() {
            return false;
        }
    
        @Override
        public void close() {
            try {
                fout.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    
    }
    

    然后通过 log4j 属性文件配置 appender

    log4j.appender.app=test.com.BinaryRollingFileAppender
    log4j.appender.app.File=/tmp/binary.bin
    log4j.appender.app.DatePattern='.'yyyy-MM-dd
    log4j.logger.app.com=DEBUG, app
    

    测试一下

    package test.com;
    
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    import org.apache.log4j.Logger;
    
    public class TestBinary {
    
        private static final Logger LOGGER = Logger.getLogger(TestBinary.class);
    
        public static void main(String[] args) {
            Path path = Paths.get("c://tmp/binary-example-file.bin");
            try {
                LOGGER.debug(Files.readAllBytes(path));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    我不知道这是否是您想要的,但这是一个很好的起点,希望这对您有所帮助。

    【讨论】:

    • 嗨,我对你的例子有疑问。 TestBinary 中的 LOGGER 实例如何使用自定义 BinaryRollingFileAppender?通过一些自定义 appender 示例,我看到人们创建自定义 appender 实例并将其附加到 LOGGER 实例。这是我们如何将自定义附加程序附加到 LOGGER 或任何其他方式?
    • 通过 log4j 属性文件,第 1 行,log4j.appender.app=test.com.BinaryRollingFileAppender,该行定义了 appender 类。
    【解决方案3】:

    您可以将RotatingFileOutputStreamrotating-fos Java 库提供的DailyRotationPolicy 一起使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-27
      • 2014-01-16
      • 2011-09-18
      • 1970-01-01
      • 2021-12-19
      • 2011-11-15
      相关资源
      最近更新 更多