我正在编写一个Java程序,它存储用户使用该程序时的日志。
为了避免使
log.log
文件(稍后可能替换为变量以在不同文件中保存不同的日志)大小太大,我想检查文件大小是否大于例如1024字节(即1kb) ,在添加新日志历史记录之前将删除最旧的数据(前几行),以确保在添加新日志之前文件大小不会大于 1kb。 (或者可以在添加日志历史记录后完成,并确保文件大小必须小于1kb。)
这意味着如果删除1行可以让文件大小小于1kb,那么只需删除第一行即可。如果还不够,则删除前两行,依此类推
public void getLogHistory(String logContent) {
File logFiles = new File("log.log"); // This is just a test, I may check to a variable and save to different log files under different situation
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
String logStatement = "[" + timestamp.toString() + "] | " + logContent;
try {
logStatement += "\n";
Files.write(Paths.get("log.log"), logStatement.getBytes(), StandardOpenOption.APPEND);
} catch (IOException e) {
}
}
我通过 Stack Overflow 或互联网检查了不同的方法。然而,所有这些都在教授创建临时文件来存储和更新所需的所有数据,然后将临时文件替换为原始文件的方法。
通过这种方法,我无法计算临时文件中的行数,因此,我不想创建临时文件来删除行。
有什么方法可以做到吗?或者我原来的代码有什么需要改进的吗?
切断所有有关日志记录的讨论(当然可以通过使用日志记录框架或 JDK Logging 更好地解决这个问题),您的问题是在向文件末尾添加一些新字节之前从文件开头删除一些字节它。
“一些字节”意味着没有行的概念;如果您坚持使用行,则必须从文件开头搜索到第一个 EOL 标记以获取要删除的字节数;事实上,这是要保留的字节的起始位置,现在您移动到位置 0。
java.io.RandomAccessFile
。
移动字节可以这样完成(但这是效率最低的解决方案!):
public final void stripFirstBytes( final RandomAccessFile file, final long lengthToStrip )
{
var writePos = 0L;
var readPos = lengthToStrip;
file.seek( readPos++ );
final var value = file.read();
while( value != EOF )
{
file.seek( writePos++ );
file.write( value );
file.seek( readPos++ );
value = file.read();
}
file.setLength( file.getFilePointer() - lengthToStrip );
}
当然,您必须添加强制错误处理(如果文件短于
lengthToStrip
,会发生什么?)!而且,如前所述,这种方法非常慢。