#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() устарел.