Last Updated on 2022-07-26 by Clay
今天我在處理多文件讀取合併時需要保留每個文件的結束點(End Of the File, EOF),並且我希望能夠逐行讀取,避免一次載入整個文件對記憶體帶來的負擔。
既然如此,我們打從一開始就得排除 open()
後使用 read()
及 readlines()
等方法來讀取文件,因為這些方法會一次性全部載入記憶體。
假設我想讀的檔案格式如下:
t
o
d
a
y
i
s
a
n
i
c
e
d
a
y
我本來以為最簡單的方法是:
# coding: utf-8
def main():
f = open("file.txt", "r")
for line in f:
print(repr(line))
f.close()
if __name__ == "__main__":
main()
Output:
't\n'
'o\n'
'd\n'
'a\n'
'y\n'
'\n'
'i\n'
's\n'
'\n'
'a\n'
'\n'
'n\n'
'i\n'
'c\n'
'e\n'
'\n'
'd\n'
'a\n'
'y\n'
然後,你可以看到我並沒有捕捉到文件的結尾 EOF。在 Python 中,EOF 應該被視為一個空字串才是。
後來我發現,這種要確認 EOF 的情況,使用 readline()
來處理才是比較恰當的。
使用方法如下方程式碼:
# coding: utf-8
def main():
f = open("file.txt", "r")
while True:
line = f.readline()
print(repr(line))
if not line:
break
f.close()
if __name__ == "__main__":
main()
Output:
't\n'
'o\n'
'd\n'
'a\n'
'y\n'
'\n'
'i\n'
's\n'
'\n'
'a\n'
'\n'
'n\n'
'i\n'
'c\n'
'e\n'
'\n'
'd\n'
'a\n'
'y\n'
''
如輸出所示,這次我們在文件的結尾捕捉到了一個可以視為 EOF 位置的空字串。這就是我想要達到的效果。
或許是篇沒什麼用又有些刁鑽的紀錄,但確實是個讓我又更了解了 Python 讀取文件機制的好問題。既然將問題解決了,便權當作個紀錄在這裡寫下。
References
- https://stackoverflow.com/questions/15599639/what-is-the-perfect-counterpart-in-python-for-while-not-eof
- https://www.geeksforgeeks.org/correcting-eof-error-in-python-in-codechef/