我尝试创建一个日志文件类,我想要遵循的过程是:
该文件的大小为1024KB(SIZE_KB常量)。
到目前为止,这就是我正在做的事情:
我创建的文件具有对所有者的读写权限(S_IRUSR | S_IWUSR)和其余的读取权限(S_IRGRP | S_IROTH)。
// Open the file. If the file doesnt exists it will create it
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
int fd = open(path.c_str(), O_CREAT | O_RDWR, mode);
之后,我会检查fd
是否为-1
:
if (fd < 0)
throw std::system_error(errno, std::system_category(), "couldnt open history");
#ifdef _DEBUG_
std::clog << "History with file descriptor " << fd << " opened" << std::endl;
#endif
现在,我映射文件,但首先我需要设置一个变量长度,文件大小必须是sysconf(_SC_PAGE_SIZE)
的多个:
size_t length = (int)ceil(SIZE_KB*1024.0/sysconf(_SC_PAGE_SIZE))*sysconf(_SC_PAGE_SIZE);
/* ceil( size / page_size)*page_size*/
#ifdef _DEBUG_
std::clog << "Length is " << length << " bytes" << std::endl;
#endif
映射,block_start
是一个私有字符指针:
block_start = (char*)mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
检查错误:
#ifdef _DEBUG_
std::clog << Returned: " << (int*)block_start << std::endl;
#endif
if (block_start == MAP_FAILED)
throw std::system_error(errno, std::system_category(), "couldnt map memory");
#ifdef _DEBUG_
std::clog << "History memory mapped" << std::endl;
#endif
关闭文件:
int result = close(fd);
if (result < 0)
throw std::system_error(errno, std::system_category(), "error closing history");
#ifdef _DEBUG_
std::clog << "History with file descriptor " << fd << " closed" << std::endl;
#endif
现在,我应该能够向映射内存添加信息,所以我尝试了:
std::cout << "Attemping to write on first" << std::endl;
*block_start = 'A';
std::cout << "End" << std::endl;
(在构造函数内)
这是我的输出:
History with file descriptor 3 opened
Length is 1048576 bytes
Returned: 0x7f7e9160a000
History memory mapped
History with file descriptor 3 closed
Attemping to write on first
Bus error (core dumped)
我认为它可能与文件大小有关,因为创建的文件大小为0,但我告诉mmap映射SIZE_KB*1024
字节的大小,为什么这不起作用?
-rw-r--r-- 1 dark dark 0 Dec 13 16:15 /home/dark/talk.log
答案 0 :(得分:1)
因为mmap的映射不会超出文件的大小。如果您正在对空文件进行mmaping,则有效的mmap大小为0。
你需要通过truncate()或ftruncate()来设置文件的大小,然后才能进行mmaping,文件大小和mmapped大小必须一致。