Должен ли я держать файл открытым или мне нужно часто открывать и закрывать?

Можно ли в таком случае открыть файл только один раз?

#!/usr/bin/env perl
use warnings;
use 5.012;
use autodie;

my $file = 'my_file';

open my $fh, '>>', $file;
say $fh "Begin";
close $fh;

$SIG{INT} = sub { 
    open my $fh, '>>', $file; 
    say $fh "End";
    close $fh;
    exit 
};

my $result;
while ( 1 ) {
    $result++;
    # ...
    # ...
    # ...
    open my $fh, '>>', $file; 
    say $fh $result;
    close $fh;
    sleep 3;
}

Ответ 1

Короткий ответ: почти всегда вы должны открывать/закрывать только один раз. Подробнее.

Решение о том, нужно ли это сделать, зависит от 4 вещей:

  • Существуют ли другие процессы, которые могут потребоваться для записи в файл?

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

  • Есть ли много файлов, которые вам нужно открыть?

    Если это так, вы можете столкнуться с файловыми дескрипторами со слишком большим количеством открытых файлов, поэтому вам нужно закрыть.

  • Сколько у вас терпимости к потере данных в файле, если программа выйдет из строя.

    Если вам нужно сохранить данные из буфера в файл, вам нужно его очистить. Это МОЖЕТ быть сделано путем частого закрытия, хотя лучшим решением является либо частая промывка, либо автозаполнение на ручке файла.

  • Вы заботитесь о том, чтобы не закрыть файл после окончания дискового пространства?

    Если это так, чем чаще вы закрываете/открываете файл, тем меньше данных вы потеряете из-за того, что файловая система заполнена, поэтому все, что вы написали с последнего open, исчезло.

В любом другом сценарии, только один раз открывать/закрывать (ну, а может быть и лишнее закрыть в обработчике __DIE__ и END{} block (и большинство времени вы, вероятно, будете в других сценариях).

Это связано с тем, что открытие/закрытие файла просто приводит к изъятию системных ресурсов без каких-либо причин И делает ваш код длиннее. Чтобы быть более конкретным, открывать и закрывать файлы являются дорогостоящими операциями, требующими как системные вызовы (которые могут заставить переключиться на ядро ​​из userland), так и дополнительный диск IO, который является ОЧЕНЬ дорогим ресурсом. Чтобы убедиться, что запустите некоторую утилиту измерения использования системы в вашей ОС и запустите Perl script, который ничего не делает, кроме открытого/закрывающего 10000 различных имен файлов в 100 раз каждый.

Обратите внимание (в отношении сценариев № 3/№ 4), что, если вам очень важно не потерять какие-либо данные, вы не должны использовать файл IO в первую очередь - используйте базу данных или обмен сообщениями с гарантией доставки.

Ответ 2

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

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

В примере, который вы показываете, дополнительные операции открытия и закрытия являются излишними (и, вероятно, будут дорогими с точки зрения производительности и системных издержек).