mmap映射的文件保存之后重新打开,为什么除了前几个字节之外数据都丢失了?

发布于 2022-09-01 05:31:26 字数 1631 浏览 31 评论 0

我正在写一个简单的本地缓存,我希望将缓存的内容映射到硬盘文件上。但是我重新打开这个文件之后发现除了开头的几个字节之外,其他部分的数据全部丢失了(变成0).
以下是文件映射部分的源码(C++):

    template <typename K, typename V>
    void *cache<K, V>::attachFile(const char *pathname, size_t length) {
        int fd;
        struct stat statbuff;
        if (stat(pathname, &statbuff) == -1) {
            fd = open(pathname, O_RDWR|O_CREAT|O_EXCL, 0644);
            if (fd == -1)
                errexit("open O_CREAT");
            if (ftruncate(fd, length) == -1) {
                close(fd);
                errexit("ftruncate");
            }
        }
        else {
            if (static_cast<size_t>(statbuff.st_size) != length)
                errexit("length is not correct.");
            fd = open(pathname, O_RDWR);
            if (fd == -1)
                errexit("open O_RDWR");
        }
        void *addr = mmap(NULL, length, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
        close(fd);
        if (addr == MAP_FAILED)
            errexit("mmap");
        //  return NULL;
        return addr;
    }

    template <typename K, typename V> 
    void cache<K, V>::releaseFile(void *addr, size_t length) {
        if (addr != NULL && length != 0) {
            if (msync(addr, length, MS_SYNC) == -1) 
                errexit("msync");
            if (munmap(addr, length) == -1) 
                errexit("munmap");
        }
    }

完整代码在https://github.com/choleraehyq/lightcache
我的开发平台是ubuntu14.04,编译器是G++4.9.2,查看了APUE没有发现什么问题,请问这可能是什么原因造成的呢?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情话墙 2022-09-08 05:31:26

楼主,做了单元测试了么?我用你的代码测了一下,没有问题啊:

#include <fcntl.h> // for open
#include <unistd.h> // for close ftruncate
#include <sys/mman.h> // for mmap
#include <sys/stat.h> // for stat

#include <stdio.h> // for perror
#include <stdlib.h> // for exit
#include <stdint.h> // for uint8_t

void reportErrorAndExit(const char* msg, const char* file, int line)
{
    fprintf(stderr, "[%s: %d]", __FILE__, __LINE__);
    perror(msg);
    exit(-1);
}

#define errexit(msg) reportErrorAndExit(msg, __FILE__, __LINE__)

    void *attachFile(const char *pathname, size_t length) {
        int fd;
        struct stat statbuff;
        if (stat(pathname, &statbuff) == -1) {
            fd = open(pathname, O_RDWR|O_CREAT|O_EXCL, 0644);
            if (fd == -1)
                errexit("open O_CREAT");
            if (ftruncate(fd, length) == -1) {
                close(fd);
                errexit("ftruncate");
            }
        }
        else {
            if (static_cast<size_t>(statbuff.st_size) != length)
                errexit("length is not correct.");
            fd = open(pathname, O_RDWR);
            if (fd == -1)
                errexit("open O_RDWR");
        }
        void *addr = mmap(NULL, length, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
        close(fd);
        if (addr == MAP_FAILED)
            errexit("mmap");
        //  return NULL;
        return addr;
    }

    void releaseFile(void *addr, size_t length) {
        if (addr != NULL && length != 0) {
            if (msync(addr, length, MS_SYNC) == -1) 
                errexit("msync");
            if (munmap(addr, length) == -1) 
                errexit("munmap");
        }
    }

int main(int argc, char* argv[])
{
    if(argc < 3) {
        fprintf(stderr, "usage: %s file length\n", argv[1]);
        return -1;
    }

    size_t length = static_cast<size_t>(atol(argv[2]));
    uint8_t* addr = static_cast<uint8_t*>(attachFile(argv[1], length));

    for(size_t i = 0; i < length; ++i) {
        addr[i] = i & 0xff;
    }

    releaseFile(addr, length);

    return 0;
}

建议楼主:建议楼主单独测一下这两个方法,再检查一下其他部分的代码。
我的环境:Ubuntu 12.04, g++ 4.6.3

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文