简体   繁体   English

阅读不断增长的文件

[英]Read the continuously growing file

I ran the command PROGRAM 2> log.txt , 我运行命令PROGRAM 2> log.txt

and it will write the output to log.txt continuously. 它将连续将输出写入log.txt。

and the output will in the same line, because every the output only has \\r in the end. 并且输出将在同一行中,因为每个输出最后都只有\\r

I'm trying to read the log.txt in that way, with truncate to clear the data I've read. 我正在尝试以这种方式读取log.txt,并进行truncate以清除已读取的数据。

    read_in_file = open(in_file, 'r')
    records = []
    for new_item in self.__get_matched_line(read_in_file):
        records.append(new_item)

    read_in_file.truncate()
    read_in_file.close()
    return records

But it has some problem, I still get the have-read data sometime. 但这有一些问题,我有时还是会得到已读取的数据。

The program may run for weeks.and it outputs every 0.5 seconds 该程序可能运行数周,每0.5秒输出一次

Your PROGRAM will have an open file handle on the output file; 您的PROGRAM在输出文件上将有一个打开的文件句柄; therefore even if you truncate the file from the outside, the file handle will write to its old position, no matter how your file had been truncated. 因此,即使从外部截断文件,无论文件如何截断,文件句柄都将写入其旧位置。 The result will be a file of the original length before the truncation (the gap is filled with zeros, maybe read about sparse files for more details if you choose this path). 结果将是截断前的原始长度的文件(间隙填充为零,如果选择此路径,则可能会阅读有关稀疏文件的更多详细信息)。 You can circumvent that by closing the file handle and opening it anew for each line. 您可以通过关闭文件句柄并为每一行重新打开它来规避该问题。 This is best done within PROGRAM of course. 当然,最好在PROGRAM中完成此操作。 If you cannot change that, you can read line-by-line (delimited by '\\r' ) and append whole lines to your log file: 如果您不能更改它,则可以逐行读取(以'\\r'分隔),并将整行附加到日志文件中:

PROGRAM |& while IFS= read -e -d $'\r' line; do echo "$line" >> log.txt; done

In case you really only want stderr to be logged this way, use this pattern: 如果您真的只希望以这种方式记录stderr,请使用以下模式:

(PROGRAM 2>&1 1>&3 | while IFS= read -e -d $'\r' line; do echo "$line" >> log.txt; done) 3>&1

This way, a truncate on the log file will have the desired effect. 这样,对日志文件进行truncate将具有所需的效果。

But consider that using truncate will only remove stuff from the end of the file while keeping the beginning. 但是请考虑使用truncate只会从文件末尾删除内容,同时保留开头。 There is no way to keep the end while removing the beginning if you use just one file. 如果仅使用一个文件,则在删除开头时无法保留结尾。 So using truncate to remove the parts you already read only makes sense if you truncate the whole file (set it to 0 bytes). 因此,如果您截断整个文件(将其设置为0字节),则使用truncate删除已经读过的部分才有意义。

So you might want to consider log rotation . 因此,您可能需要考虑日志轮换 That's a well-defined process which may have advantages over your approach (and be it only that there are facilities which already do it for you). 这是一个定义明确的过程,它可能比您的方法更具优势(而且仅仅是因为已经有一些设施可以为您做到)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM