Кажется, что метод .tell () не очень надежен при работе с текстовыми файлами в python. Я пытаюсь использовать этот метод, чтобы заменить условие EOF, как в других языках программирования.
По разным причинам я не хочу перебирать текстовый файл с циклом FOR, а вместо этого использую цикл WHILE.
Ниже приведен код, который повторяет проблему. Я включил код, который будет генерировать текстовый файл test.txt случайным образом:
import re
from random import randint
def file_len_lines(f_name):
with open(f_name) as f:
for i, l in enumerate(f):
pass
return i + 1
def file_len_chars(f_name, with_nls):
char_count = 0
with open(f_name) as f:
for line in f:
char_count += len(line)
if with_nls:
char_count += 1
else:
pass
return char_count
def trim(sut):
return re.sub(' +', ' ', sut).strip()
# Create test file
with open("test.txt", "w") as f:
word_list = ("Betty Eats Cakes And Uncle Sells Eggs "*20).split()
word_list[3] = ""
# for num in range(len(word_list)):
# if randint(1, 2) == 1:
# word_list[num] = ""
for word in word_list:
print(word, file=f)
file_to_read = 'test.txt'
# file_to_read = 'Fibonacci Tree 01.log'
with open(file_to_read, "r") as f:
count = 0
file_length = file_len_chars(file_to_read, True)
file_length_lines = file_len_lines(file_to_read)
print(f"Lines in file = {file_length_lines}, Characters in file = {file_length}")
f.seek(0)
while f.tell() < file_length:
count += 1
text_line = f.readline()
print(f"Line = {count}, ", end="")
print(f"Tell = {f.tell()}, ", end="")
print(f"Length {len(text_line)} ", end="")
if text_line in ['', '\n']:
print(count)
elif trim(text_line).upper()[0] in "A E I O U".split():
print(text_line, end='')
else:
print(count)
Этот код должен всегда выводить что-то вроде:
Lines in file = 140, Characters in file = 897
Line = 1, Tell = 7, Length 6 1
Line = 2, Tell = 13, Length 5 Eats
Line = 3, Tell = 20, Length 6 3
...
Line = 138, Tell = 884, Length 6 Uncle
Line = 139, Tell = 891, Length 6 139
Line = 140, Tell = 897, Length 5 Eggs
Process finished with exit code 0
но вместо этого он в основном выводит что-то похожее на:
Lines in file = 140, Characters in file = 605
Line = 1, Tell = 7, Length 6 1
Line = 2, Tell = 18446744073709551630, Length 5 Eats
Process finished with exit code 0
Вы можете видеть, что в последней строке вывода выше вывод метода .tell () стал бесполезным и не прошел все 140 строк.
Я ищу способ заставить метод .tell () вести себя или иным образом обнаруживать условие EOF другим способом, чтобы прервать цикл WHILE.
Опять же, большинство советов, найденных в Интернете, гласят: "итерация с циклом FOR" Я не хочу делать это по разным причинам, которые утомительно объяснять. (Вкратце, это сделает мою исходную программу очень громоздкой из-за вложенной блок-схемы, которой я собираюсь следовать.)