Повторное чтение из уже прочитанного дескриптора файла

Я открыл файл для чтения из строки за строкой:

open(FH,"<","$myfile") or die "could not open $myfile: $!";
while (<FH>)
{
    # ...do something
}

Позже в программе я попытаюсь перечитать файл (снова пройдите через файл):

while (<FH>)
{
    # ...do something
}

и понял, что он как будто элемент управления внутри файла находится в EOF и не будет перебираться из первой строки в файле.... это поведение по умолчанию? Как обойти это? Файл большой, и я не хочу хранить в памяти массив. Мой единственный вариант - закрыть и снова открыть файл?

Ответ 1

Используйте поиск для перемотки назад в начало файла:

seek FH, 0, 0;

Или, будучи более подробным:

use Fcntl;
seek FH, 0, SEEK_SET;

Обратите внимание, что это сильно ограничивает полезность вашего инструмента, если вы должны искать на входе, так как он никогда не может использоваться в качестве фильтра. Очень полезно иметь возможность читать из трубы. Имея в виду, что 57% всех статистических данных составлены, вы должны понимать, что 98% программ, которые ищут на их входе, делают это бесполезно. Очень старайтесь обрабатывать данные таким образом, чтобы вам не нужно было дважды читать их. Если это возможно, ваша программа будет намного полезнее.

Ответ 2

У вас есть несколько вариантов.

  • Повторно открыть дескриптор файла
  • Задайте позицию в начале файла, используя seek, как предположил Уильям Пурселл.
  • Используйте модуль, например Tie:: File, который позволяет вам читать файл как массив, не загружая его в память.