内存映射文件问题

Memory mapped file problems

本文关键字:问题 文件 映射 内存      更新时间:2023-10-16

在我的c++代码中,我需要将大量数据写入文件,我想使用boost映射文件而不是使用正常文件。只有当我写完内存中的所有数据时,我才想一次性将映射文件转储到磁盘。

我在Windows Server 2008 R2和boost 1.58上使用Visual Studio 2010。

我从来没有使用过映射文件,所以我试图在boost文档

上编译示例
#include <iostream>
#include <fstream>
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>

int main(int argc, char** argv) 
{
    using namespace boost::interprocess;
const char* fileName = "C:\logAcq\test.bin";
const std::size_t fileSize = 10000;
std::cout << "create file" << std::endl;
try
{
    file_mapping::remove(fileName);
    std::filebuf fbuf;
    fbuf.open(fileName, std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
    std::cout << "set size" << std::endl;
    fbuf.pubseekoff(fileSize-1, std::ios_base::beg);
    fbuf.sputc(0);
    std::cout << "remove on exit" << std::endl;
    struct file_remove
    {
        file_remove(const char* fileName)
            :fileName_(fileName) {}
        ~file_remove(){ file_mapping::remove(fileName_); }
        const char *fileName_;
    }remover(fileName);
    std::cout << "create file mapping" << std::endl;
    file_mapping m_file(fileName, read_write);
    std::cout << "map the whole file" << std::endl;
    mapped_region region(m_file, read_write);
    std::cout << "get the address" << std::endl;
    void* addr = region.get_address();
    std::size_t size = region.get_size();
    std::cout << "write all memory to 1" << std::endl;
    memset(addr, 1, size);
}
catch (interprocess_exception &ex) 
{
    fprintf(stderr, "Exception %sn", ex.what());
    fflush(stderr);
    system("PAUSE");
    return 0;
}
system("PAUSE");
return 0;
}

但是我得到了异常

异常:文件的卷被外部修改,打开的文件不再有效。

创建区域

"mapped_region region(m_file, read_write)"

任何帮助都是非常感谢的。

谢谢

异常文件的卷被外部修改,打开的文件不再有效。

强烈提示文件在被映射时被另一个程序更改。并且错误信息表明发生的更改以不允许的方式影响大小。

避免其他程序写入文件,或有适当的同步和共享预防措施(如,不要改变大小,或只增长等)

您添加的SSCCE确认您在映射时保持文件打开:

映射文件前需要关闭fbuf。此外,您需要在允许删除映射之前删除映射。

工作示例:

Live On Coliru

#include <iostream>
#include <fstream>
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>
int main() {
    using namespace boost::interprocess;
    const char *fileName = "test.bin";
    const std::size_t fileSize = 10000;
    std::cout << "create file " << fileName << std::endl;
    try {
        file_mapping::remove(fileName);
        {
            std::filebuf fbuf;
            fbuf.open(fileName, std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
            std::cout << "set size" << std::endl;
            fbuf.pubseekoff(fileSize - 1, std::ios_base::beg);
            fbuf.sputc(0);
        }
        std::cout << "remove on exit" << std::endl;
        struct file_remove {
            file_remove(const char *fileName) : fileName_(fileName) {}
            ~file_remove() { file_mapping::remove(fileName_); }
            const char *fileName_;
        } remover(fileName);
        {
            std::cout << "create file mapping" << std::endl;
            file_mapping m_file(fileName, read_write);
            std::cout << "map the whole file" << std::endl;
            mapped_region region(m_file, read_write);
            std::cout << "get the address" << std::endl;
            void *addr = region.get_address();
            std::size_t size = region.get_size();
            std::cout << "write all memory to 1" << std::endl;
            memset(addr, 1, size);
        }
    } catch (interprocess_exception &ex) {
        fprintf(stderr, "Exception %sn", ex.what());
        fflush(stderr);
    }
}