2015-10-16 155 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

該文件由代碼本身創建。我已經發布了代碼... –