Усечение файла с отображением памяти

#c #ios #mmap

#c #iOS #mmap

Вопрос:

Я хотел бы использовать файл с отображением памяти для чтения / записи для управления некоторыми индексами ( unsigned int ), которые я создаю.

Я следил за примерами кода, найденными здесь и здесь

Я не знаю размер файла изначально, поэтому я планирую сделать его примерно 4K для начала и соответственно увеличить.

Однако я не уверен, как обрезать файл, как только я закончу с картой. Поэтому, если я использую только около 1 КБ в файле, я хотел бы сократить его до 1 КБ и не тратить 3 КБ в процессе. Я беспокоюсь не о том, чтобы тратить впустую файловое пространство, а скорее проверяю размер файла, чтобы определить, сколько unsigned int у меня есть.

Редактировать

Итак, чтобы уточнить … пока файл сопоставлен с памятью…Я выделяю 4K фрагментов…когда я закончу с файлом с отображением памяти, я хочу очистить файл, чтобы он был именно тем, что я в него вложил.

Ответ №1:

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

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

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

Ответ №2:

Если вы ftruncate() файл, вам придется «одновременно» mremap() сопоставление с новым размером. Вы можете сделать аналогичную вещь для экстентов (но это может привести к тому, что mremap поместит сегмент в другую часть вашего адресного пространства)

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

1. Я думаю, что mremap() не является стандартом function…so Я просто munmap(), затем mmap() … во всяком случае, ftruncate() работает для меня…

2. Вы правы. Это не в POSIX. У Linux это есть, у True64 / OSF это было. похоже, у BSD есть один с другой семантикой. Но: если он присутствует, это, вероятно, дешевле, чем комбинация munmap() mmap() .

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

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

Ответ №3:

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

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

1. Я уточнил свой question…my намерение состоит не в том, чтобы усекать, пока файл сопоставлен с памятью … а скорее после того, как я закончу с файлом…

2. Аналогично для файловой системы. Проверьте размер блока файла для вашей системы, я думаю, что это 4 КБ или даже больше.

3. Правильно… Я понимаю, что файлы имеют размер блока, но, как я упоминал в своем вопросе, я проверяю размер файла, чтобы определить, сколько у меня целых чисел без знака. Кроме того, я обнаружил, что getpagesize() устарел.