簡體   English   中英

Python - 如何打開文件並以字節為單位指定偏移量?

[英]Python - How can I open a file and specify the offset in bytes?

我正在編寫一個程序,它會定期解析Apache日志文件以記錄它的訪問者,帶寬使用情況等。

問題是,我不想打開日志並解析我已經解析過的數據。 例如:

line1
line2
line3

如果我解析該文件,我將保存所有行,然后保存該偏移量。 這樣,當我再次解析它時,我得到:

line1
line2
line3 - The log will open from this point
line4
line5

第二輪,我會得到第4行和第5行。 希望這是有道理的......

我需要知道的是,我該如何做到這一點? Python有seek()函數來指定偏移量...所以我只是在解析之后得到日志的文件大小(以字節為單位)然后在第二次記錄它時使用它作為偏移量(在seek()中)?

我似乎無法想到一種編碼方式>。<

您可以通過file類的seektell方法管理文件中的位置,請參閱https://docs.python.org/2/tutorial/inputoutput.html

tell方法將告訴您下次打開時的位置

log = open('myfile.log')
pos = open('pos.dat','w')
print log.readline()
pos.write(str(f.tell())
log.close()
pos.close()

log = open('myfile.log')
pos = open('pos.dat')
log.seek(int(pos.readline()))
print log.readline()

當然你不應該這樣使用它 - 你應該將操作包裝在save_position(myfile)load_position(myfile)等函數中,但功能就在那里。

如果您的日志文件很容易適合內存 (這是一個合理的輪換策略),您可以輕松地執行以下操作:

log_lines = open('logfile','r').readlines()
last_line = get_last_lineprocessed() #From some persistent storage
last_line = parse_log(log_lines[last_line:])
store_last_lineprocessed(last_line)

如果你不能這樣做,你可以使用類似的東西(參見接受的答案使用搜索和告訴,以防你需要使用它們) 使用Python獲取文件的最后n行,類似於尾部

如果您要解析每行的日志行,則可以從最后一次解析中獲取保存行號。 你可能會在下次開始從好線開始讀它。

當您必須在文件中的特定位置時,尋求更有用。

容易但不推薦:):

last_line_processed = get_last_line_processed()    
with open('file.log') as log
    for record_number, record in enumerate(log):
        if record_number >= last_line_processed:
            parse_log(record)

請注意,您可以從文件末尾的python中搜索():

f.seek(-3, os.SEEK_END)

將讀取位置放在EOF的3行。

但是,為什么不使用來自shell或difflib的diff

這是代碼證明使用你的長度消息和告訴methond:

beginning="""line1
line2
line3"""

end="""- The log will open from this point
line4
line5"""

openfile= open('log.txt','w')
openfile.write(beginning)
endstarts=openfile.tell()
openfile.close()

open('log.txt','a').write(end)
print open('log.txt').read()

print("\nAgain:")
end2 = open('log.txt','r')
end2.seek(len(beginning))

print end2.read()  ## wrong by two too little because of magic newlines in Windows
end2.seek(endstarts)

print "\nOk in Windows also"
print end2.read()
end2.close()

這是一個有效且安全的代碼片段,用於保存parallell文件中的偏移讀取。 基本上是python中的logtail。

with open(filename) as log_fd:
    offset_filename = os.path.join(OFFSET_ROOT_DIR,filename)
    if not os.path.exists(offset_filename):
        os.makedirs(os.path.dirname(offset_filename))
        with open(offset_filename, 'w') as offset_fd:
            offset_fd.write(str(0))
    with open(offset_filename, 'r+') as offset_fd:
        log_fd.seek(int(offset_fd.readline()) or 0)
        new_logrows_handler(log_fd.readlines())
        offset_fd.seek(0)
        offset_fd.write(str(log_fd.tell()))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM