Почему я не могу вызвать read() дважды в открытом файле?



для упражнения, которое я делаю, я пытаюсь прочитать содержимое данного файла дважды, используя read() метод. Странно, когда я вызываю его во второй раз, он, кажется, не возвращает содержимое файла в виде строки?



здесь код



f = f.open()

# get the year
match = re.search(r'Popularity in (d+)', f.read())

if match:
print match.group(1)

# get all the names
matches = re.findall(r'<td>(d+)</td><td>(w+)</td><td>(w+)</td>', f.read())

if matches:
# matches is always None


конечно, я знаю, что это не самый эффективный и лучший способ, это не суть. Дело в том, почему я не могу позвонить read() в два раза? Мне нужно сбросить дескриптор файла? Или закрыть / открыть файл для того, чтобы сделать это?

623   7  

7 ответов:

вызов read() считывает весь файл и оставляет курсор чтения в конце файла (только для чтения). Если вы хотите прочитать определенное количество строк за один раз, вы можете использовать readline(),readlines() или перебирать строки с for line in handle:.

чтобы ответить на ваш вопрос напрямую, как только файл был прочитан, с read() можно использовать seek(0) чтобы вернуть курсор чтения в начало файла (docs are здесь). Если вы знаете, что файл не является будет слишком большой, вы также можете сохранить read() вывод в переменную, используя ее в выражениях findall.

Ps. Не забудьте закрыть файл после того, как вы закончите с ним ;)

да, как выше...

Я напишу только пример:

>>> a = open('file.txt')
>>> a.read()
#output
>>> a.seek(0)
>>> a.read()
#same output

всем, кто ответил на этот вопрос до сих пор абсолютно прав - read() перемещается по файлу, поэтому после того, как вы его вызвали, Вы не можете вызвать его снова.

Я добавлю, что в вашем конкретном случае вам не нужно искать назад к началу или снова открывать файл, вы можете просто сохранить текст, который вы прочитали в локальной переменной, и использовать его дважды или столько раз, сколько вам нравится, в вашей программе:

f = f.open()
text = f.read() # read the file into a local variable
# get the year
match = re.search(r'Popularity in (\d+)', text)
if match:
  print match.group(1)
# get all the names
matches = re.findall(r'<td>(\d+)</td><td>(\w+)</td><td>(\w+)</td>', text)
if matches:
  # matches will now not always be None

указатель чтения перемещается после последнего прочитанного байта / символа. Используйте seek() метод для перемотки указателя чтения в начало.

каждый открытый файл имеет соответствующую позицию.
Когда вы читаете (), Вы читаете с этой позиции. Например read(10) считывает первые 10 байт из вновь открытого файла, затем еще один read(10) считывает следующие 10 байт. read() без аргументов считывает все содержимое файла, оставляя позицию файла в конце файла. В следующий раз, когда вы позвоните read() читать нечего.

можно использовать seek для перемещения позиции в файле. Или, возможно, лучше в вашем случае будет быть, чтобы сделать один read() и сохранить результат для обоих поисков.

read()потребляет. Так что, вы могли бы сброс файл, или искать для начала перед повторным чтением. Или, если это соответствует вашей задаче, вы можете использовать read(n) потреблять только n байт.

Я всегда нахожу метод чтения чем-то вроде прогулки по темному переулку. Вы спускаетесь немного вниз и останавливаетесь, но если вы не считаете свои шаги, вы не уверены, как далеко вы находитесь. Seek дает решение путем перемещения, другой вариант-сказать, который возвращает позицию вдоль файла. Может быть, Python file api может комбинировать чтение и поиск в read_from(позиция, байты), чтобы сделать его проще - пока это не произойдет, вы должны прочитать на этой странице.

Comments

    Ничего не найдено.