Java 滚动文件实现

Java 滚动文件实现,java,file,logging,filewriter,rollingfileappender,Java,File,Logging,Filewriter,Rollingfileappender,我总是好奇如何在日志中实现滚动文件 为了确保不超过文件大小,人们如何开始用任何语言创建文件编写类 我能想到的唯一可能的解决办法是: write method: size = file size + size of string to write if(size > limit) close the file writer open file reader read the file close file rea

我总是好奇如何在日志中实现滚动文件

为了确保不超过文件大小,人们如何开始用任何语言创建文件编写类

我能想到的唯一可能的解决办法是:

write method:
    size = file size + size of string to write
    if(size > limit)
        close the file writer
        open file reader
        read the file
        close file reader
        open file writer (clears the whole file)
        remove the size from the beginning to accommodate for new string to write
        write the new truncated string
    write the string we received
这似乎是一个可怕的实施,但我想不出更好的办法

具体来说,我希望看到一个java解决方案


编辑:从开头删除大小是,假设我有20个字节的字符串(这是限制),我想再写一个3字节的字符串,因此我从开头删除了3个字节,剩下的是17个字节,通过添加新字符串,我有20个字节。

因为你的问题让我研究它,下面是一个来自
logback
日志框架的示例。
RollingfileAppender#rollover()
方法如下所示:

public void rollover() {
    synchronized (lock) {
        // Note: This method needs to be synchronized because it needs exclusive
        // access while it closes and then re-opens the target file.
        //
        // make sure to close the hereto active log file! Renaming under windows
        // does not work for open files
        this.closeOutputStream();

        try {
            rollingPolicy.rollover(); // this actually does the renaming of files
        } catch (RolloverFailure rf) {
            addWarn("RolloverFailure occurred. Deferring roll-over.");
            // we failed to roll-over, let us not truncate and risk data loss
            this.append = true;
        }

        try {
            // update the currentlyActiveFile           
            currentlyActiveFile = new File(rollingPolicy.getActiveFileName());

            // This will also close the file. This is OK since multiple
            // close operations are safe.
            // COMMENT MINE this also sets the new OutputStream for the new file
            this.openFile(rollingPolicy.getActiveFileName()); 
        } catch (IOException e) {
            addError("setFile(" + fileName + ", false) call failed.", e);
        }
    }
}
正如你所看到的,逻辑与你发布的非常相似。它们关闭当前的
OutputStream
,执行滚动,然后打开一个新的(
openFile()
)。显然,这都是在
synchronized
块中完成的,因为许多线程都在使用记录器,但一次只能发生一次滚动


RollingPolicy
是关于如何执行滚动的策略,
TriggeringPolicy
是何时执行滚动的策略。使用
logback
,这些策略通常基于文件大小或时间

因为你的问题让我对它进行了研究,这里有一个来自
logback
日志框架的示例。
RollingfileAppender#rollover()
方法如下所示:

public void rollover() {
    synchronized (lock) {
        // Note: This method needs to be synchronized because it needs exclusive
        // access while it closes and then re-opens the target file.
        //
        // make sure to close the hereto active log file! Renaming under windows
        // does not work for open files
        this.closeOutputStream();

        try {
            rollingPolicy.rollover(); // this actually does the renaming of files
        } catch (RolloverFailure rf) {
            addWarn("RolloverFailure occurred. Deferring roll-over.");
            // we failed to roll-over, let us not truncate and risk data loss
            this.append = true;
        }

        try {
            // update the currentlyActiveFile           
            currentlyActiveFile = new File(rollingPolicy.getActiveFileName());

            // This will also close the file. This is OK since multiple
            // close operations are safe.
            // COMMENT MINE this also sets the new OutputStream for the new file
            this.openFile(rollingPolicy.getActiveFileName()); 
        } catch (IOException e) {
            addError("setFile(" + fileName + ", false) call failed.", e);
        }
    }
}
正如你所看到的,逻辑与你发布的非常相似。它们关闭当前的
OutputStream
,执行滚动,然后打开一个新的(
openFile()
)。显然,这都是在
synchronized
块中完成的,因为许多线程都在使用记录器,但一次只能发生一次滚动


RollingPolicy
是关于如何执行滚动的策略,
TriggeringPolicy
是何时执行滚动的策略。使用
logback
,这些策略通常基于文件大小或时间

在日志框架中,这有点复杂,因为它们有不同的策略来执行滚动。下载源代码,例如
logback
,看看类
RollingFileAppender
FixedWindowRollingPolicy
,特别是方法
rollover()
。谢谢,这很有趣,但是如果我想创建一些简单扩展PrintWriter的东西,比如,我希望它尽可能简单和优雅?你所发布的内容有其要点,但是你从一开始就删除大小是什么意思呢?在日志框架中,它有点复杂,因为它们有不同的滚动策略。下载源代码,例如
logback
,看看类
RollingFileAppender
FixedWindowRollingPolicy
,特别是方法
rollover()
。谢谢,这很有趣,但是如果我想创建一些简单扩展PrintWriter的东西,比如,我希望它尽可能的简单和优雅?你所发布的内容有其要点,但是你从一开始就去掉尺寸是什么意思?这看起来非常低效,尽管没有?所有的日志记录都使用它吗?打开和关闭一条流是非常昂贵的,一旦你达到了最高点,这样做往往听起来很糟糕。关闭一条流?不,不是真的。显然,您不会将触发器策略设置为每秒打开一个新文件(尽管您可以)。日志框架就是这样做的。如果要写入文件,则需要打开其流。所以,做一个滚动的实现,将需要,没有办法绕过它。我不认为它的效率,因为它通常是一个零星的操作。特别是说到日志,如果它发生得太频繁,可能意味着要么你向日志发送了太多的信息,要么日志大小太小,我认为。这看起来效率非常低,但不是吗?所有的日志记录都使用它吗?打开和关闭一条流是非常昂贵的,一旦你达到了最高点,这样做往往听起来很糟糕。关闭一条流?不,不是真的。显然,您不会将触发器策略设置为每秒打开一个新文件(尽管您可以)。日志框架就是这样做的。如果要写入文件,则需要打开其流。所以,做一个滚动的实现,将需要,没有办法绕过它。我不认为它的效率,因为它通常是一个零星的操作。特别是说到日志,如果它发生得太频繁,可能意味着要么你向日志发送了太多的信息,要么日志大小太小,我认为。