2015-10-16 152 views
0

在我的C++代码中,我需要将大量数据写入文件,并且我想使用升压映射文件而不是使用普通文件。只有当我完成将所有数据写入内存时,我才想将映射文件转储到磁盘上。内存映射文件问题

我在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 %s\n", ex.what()); 
    fflush(stderr); 
    system("PAUSE"); 

    return 0; 
} 

system("PAUSE"); 

return 0; 
} 

的例子,但我得到的异常

异常文件所在的卷已被外部改变,因此打开的文件不再有效。当我创建了区域

“mapped_region区(m_file,READ_WRITE)”

任何帮助是赞赏。

感谢

+0

我看到的错误导致你的大写锁定键的行为,如果是停留在“活动”状态? – sehe

回答

1

异常的文件所在的卷已被外部改变,因此打开的文件不再有效。

强烈建议文件在映射时由另一个程序更改。并且错误消息指示发生的变化以不允许的方式影响大小。

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

UPDATE

让您SSCCE确认您在映射时将文件保持打开状态:

您需要在映射文件之前关闭。此外,您需要先删除映射,然后再将其删除。

工作样本:

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 %s\n", ex.what()); 
     fflush(stderr); 
    } 
} 
+0

嗨,没有其他进程使用该文件。该文件是由示例创建的... –

+0

您是否在VS项目中添加了该文件?谁给出错误?它在屏幕上看起来像什么? – sehe

+0

该文件由代码本身创建。我已经发布了代码... –