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

#c #linux #file-descriptor

#c #linux #файловый дескриптор

Вопрос:

Один файл размером 2 ГБ передается с сервера на клиент. На стороне клиента, после получения 512 МБ этого файла, я открываю его с помощью:

 FILE *fp= fopen("that file","r"); 
 

Теперь, после завершения загрузки, могу ли я получить доступ ко всем данным этого файла объемом 2 ГБ с помощью этого файлового дескриптора? Или мне нужно повторно открыть его, чтобы получить доступ ко всему файлу?

Комментарии:

1. Почему вы хотите открыть файл до его полной загрузки?

2. @JoachimPileborg я просто думаю, идет ли потоковая передача файла, и я хочу воспроизвести его во время этого ?!!

Ответ №1:

Во-первых, вам следует избегать пробелов в именах файлов Linux. Таким образом, ваш пример должен FILE *fp= fopen("that_file","r"); содержать пробелы (или даже управляющие символы, такие как перевод строки) в именах файлов — плохой вкус.

А в Linux файловый дескриптор (который не является FILE* дескриптором!) Представляет собой небольшое целое число, которое обрабатывается ядром: внутри ядра процессы имеют таблицу открытых файлов, и их код приложения ссылается (используя системные вызовы, такие как open и read и т.д.) На эти файлы по их файловому дескриптору. Стандартная библиотека C управляет буферизацией и файловыми дескрипторами (поэтому внутри структуры FILE данных есть буферы и файловый дескриптор).

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

Итак, вам не нужно «обновлять» ваш fp , но ваш код дерьмовый (из-за отсутствия синхронизации между процессом чтения и записи).

Комментарии:

1. 1> спасибо, что сказал о пробелах 2> что, если я открою этот файл с помощью open(), тогда мне нужно обновить fp?

2. Нет (но, возможно, вызов fsync может помочь, но я считаю, что вам это не нужно). Тем не менее, я настаиваю на том, что это плохая практика , поскольку у вас должен быть какой-то способ синхронизации процессов записи и чтения

3. @Mr .32: здесь нет разницы между open и fopen . В этом fsync тоже нет необходимости.

4. Существует огромная разница между open amp; fopen : open является системным вызовом (и вы должны буферизировать данные, чтобы избежать вызова write слишком маленьких фрагментов данных), возвращающим целочисленный файловый дескриптор. fopen это стандартная функция библиотеки C, возвращающая FILE* указатель. Вы будете использовать fprintf или fwrite для записи туда, и он буферизует для вас. См. Также fflush .

5. @BasileStarynkevitch Если быть точным, большинство современных операционных систем в некоторой степени будут выполнять буферизацию чтения / записи для вас. Контроллеры диска также будут выполнять некоторую буферизацию. Таким образом, хотя хорошей практикой является выполнение некоторого объема буферизации, это строго не требуется.

Ответ №2:

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

( FILE* Кстати, A не является файловым дескриптором.)

Комментарии:

1. возможно, потребуется fsync (особенно с реализациями на основе fuse, которым разрешено локально кэшировать статистическую информацию IIRC)

Ответ №3:

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

Комментарии:

1. Это полная бессмыслица. Открытие файла не загрузит его в память.

2. The fopen() function shall open the file whose pathname is the string pointed to by filename, and associates a stream with it.