Должен ли я держать файл открытым или я должен часто открывать и закрывать? - PullRequest
8 голосов
/ 01 февраля 2011

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

#!/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;
}

Ответы [ 2 ]

20 голосов
/ 01 февраля 2011

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

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

  1. Есть ли другие процессы, которые могут потребоваться для записи в файл?

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

  2. Есть ли МНОГО файлов, которые нужно открыть?

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

  3. Сколько терпимости вы потеряете в файле в случае сбоя программы.

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

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

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

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

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

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

4 голосов
/ 01 февраля 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...