具有较大固定长度且填充为零的 mmap 文件?
mmap file with larger fixed length with zero padding?
我想用mmap()
读取固定长度的文件(例如64MB),但也有一些文件<64MB。
我映射长度为 64MB 的文件(<64MB,例如 30MB),当读取超过文件大小(30MB - 64MB)的文件数据时,程序得到 bus-error
.
我想mmap这些固定长度的文件,当指针超出文件大小时读取0x00。怎么做?
我能想到的一种方法是先ftruncate
归档,然后ftruncate
回ori大小,但我认为这个方法并不完美。
这是 MAP_FIXED
的几个合理用例之一,用于重新映射现有映射的一部分以使用新的支持文件。
这里一个简单的解决方案是无条件地 mmap
64 MB 匿名内存(或显式 mmap /dev/zero
), 没有 MAP_FIXED
和存储结果指针。
接下来,mmap
64 MB 或实际文件的实际文件大小(以较小者为准),传递 anonymous/zero mmap
的结果并传递 MAP_FIXED
标志。与您的文件对应的页面将不再 anonymous/zero 映射,而是由您的文件数据支持;其余页面将由 anonymous/zero 页支持。
完成后,单个 munmap
调用将立即取消映射所有 64 MB(您不需要分别取消映射真实文件页面和零备份页面)。
极其简单的例子(没有查错,请自行添加):
// Reserve 64 MB of contiguous addresses; anonymous mappings are always zero backed
void *mapping = mmap(NULL, 64 * 1024 * 1024, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
// Open file and check size
struct stat sb;
int fd = open(myfilename, O_RDONLY);
fstat(fd, &sb);
// Use smaller of file size or 64 MB
size_t filemapsize = sb.st_size > 64 * 1024 * 1024 ? 64 * 1024 * 1024 : sb.st_size;
// Remap up to 64 MB of pages, replacing some or all of original anonymous pages
mapping = mmap(mapping, filemapsize, PROT_READ, MAP_SHARED | MAP_FIXED, fd, 0);
close(fd);
// ... do stuff with mapping ...
munmap(mapping, 64 * 1024 * 1024);
我想用mmap()
读取固定长度的文件(例如64MB),但也有一些文件<64MB。
我映射长度为 64MB 的文件(<64MB,例如 30MB),当读取超过文件大小(30MB - 64MB)的文件数据时,程序得到 bus-error
.
我想mmap这些固定长度的文件,当指针超出文件大小时读取0x00。怎么做?
我能想到的一种方法是先ftruncate
归档,然后ftruncate
回ori大小,但我认为这个方法并不完美。
这是 MAP_FIXED
的几个合理用例之一,用于重新映射现有映射的一部分以使用新的支持文件。
这里一个简单的解决方案是无条件地 mmap
64 MB 匿名内存(或显式 mmap /dev/zero
), 没有 MAP_FIXED
和存储结果指针。
接下来,mmap
64 MB 或实际文件的实际文件大小(以较小者为准),传递 anonymous/zero mmap
的结果并传递 MAP_FIXED
标志。与您的文件对应的页面将不再 anonymous/zero 映射,而是由您的文件数据支持;其余页面将由 anonymous/zero 页支持。
完成后,单个 munmap
调用将立即取消映射所有 64 MB(您不需要分别取消映射真实文件页面和零备份页面)。
极其简单的例子(没有查错,请自行添加):
// Reserve 64 MB of contiguous addresses; anonymous mappings are always zero backed
void *mapping = mmap(NULL, 64 * 1024 * 1024, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
// Open file and check size
struct stat sb;
int fd = open(myfilename, O_RDONLY);
fstat(fd, &sb);
// Use smaller of file size or 64 MB
size_t filemapsize = sb.st_size > 64 * 1024 * 1024 ? 64 * 1024 * 1024 : sb.st_size;
// Remap up to 64 MB of pages, replacing some or all of original anonymous pages
mapping = mmap(mapping, filemapsize, PROT_READ, MAP_SHARED | MAP_FIXED, fd, 0);
close(fd);
// ... do stuff with mapping ...
munmap(mapping, 64 * 1024 * 1024);