Присоединение к глобальному дескриптору файла, это плохо? - PullRequest
3 голосов
/ 15 сентября 2010

Допустим, в моей программе есть несколько функций, которым нужно добавлять данные в определенный файл. Я открываю файл в начале программы с помощью глобального дескриптора файла, чтобы я мог добавлять его в любое место. (Обратите внимание, что я знаю, что могу передать дескриптор файла в качестве аргумента функциям, но это не является целью этого вопроса). Разве плохо открывать дескриптор файла в начале программы, а затем закрывать его в конце; или лучше иметь функцию скажем void AppendFile(char *data_to_append);, а затем открыть файл, добавить к нему и закрыть его в этой же функции? Если программа умирает, FD все равно будет использоваться, это единственная плохая вещь, которую я вижу, но в то же время вы открываете и закрываете один и тот же файл сотни и сотни раз, если используете функцию.

Ответы [ 7 ]

2 голосов
/ 15 сентября 2010

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

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

Удостоверьтесь, что вы закрыли свой файл, хотя в конце концов.

1 голос
/ 15 сентября 2010

глобальные переменные обычно не очень хорошая вещь. Для небольших программ это не имеет значения.

Хотя по-прежнему используется глобальный дескриптор файла, попробуйте получить к нему доступ только через функцию void AppendFile(char *data_to_append);, где только AppendFile ссылается на глобальный файл, а не разбрасывает его по всему коду.

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

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

1 голос
/ 15 сентября 2010

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

Взгляните на SQLite (http://www.sqlite.org/).

Думайте о SQLite не как о замене Oracle, а как о замене fopen ()

1 голос
/ 15 сентября 2010

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

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

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

1 голос
/ 15 сентября 2010

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

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

0 голосов
/ 15 сентября 2010

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

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

Если программа является однопоточным приложением, вам не о чем беспокоиться.

Если бы вам пришлось многократно открывать, добавлять и закрывать файл, вы могли бы столкнуться с проблемами, если бы использовали stdio's FILE * с несколькими потоками или если вызовы AppendFile были каким-то образом сделаны рекурсивно, потому что разные FILE * s не будет совместно использовать буферы в приложении, и, так как файл, измененный в одном потоке, другие потоки могут перезаписать эти изменения.

Аналогичная вещь может произойти с дескрипторами файла os (целые числа, возвращаемые open), поскольку различные вызовы open будут приводить к разным дескрипторам файла, и они не будут совместно использовать свою позицию поиска, поэтому по мере роста файла различные файловые дескрипторы заканчиваются с позициями поиска, которые фактически не находились в конце файла, если вы не можете открыть файл в режиме только добавления (O_APPEND), где операционная система обрабатывает это для вас.

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

0 голосов
/ 15 сентября 2010

Да.

Не самый полезный ответ, но я боюсь, что ваш вопрос слишком общий и неопределенный, чтобы дать вам что-нибудь подробное. Если у вас есть доступ к этому FD, разбросанному по вашей программе, значит, что-то не так с вашим проектом высокого уровня. Связаны ли эти отдельные доступы каким-либо образом? Могут ли они быть объединены в меньшее количество точек, которые обращаются к файлу? У вас есть какая-то подразумеваемая структура данных в вашей программе, которую лучше реализовать в классе?

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