在VC ++中读取一个boost内存映射文件的结尾

时间:2014-10-08 08:56:51

标签: c++ visual-studio-2010 memory boost

我正在使用VS2010编写一个用C ++编写的程序来读取文本文件并从中提取某些信息。我使用filestream完成了代码,效果很好。但是现在我被要求将文件映射到内存并使用它而不是文件操作。

我绝对是内存映射的新手。我写的代码的一部分如下。

boost::iostreams::mapped_file_source apifile;

apifile.open(LogFileName,LogFileSize);

if(!apifile.is_open()) 

return FILE_OPEN_ERROR;

// Get pointer to the data.

PBYTE Buffer = (PBYTE)apifile.data();

while(//read till end of the file)
{
     // read a line and check if it contains a specific word
}

在使用文件流时,我会使用eofgetline以及string::find来执行操作。但我不知道如何使用内存映射文件来做到这一点。

编辑1:

int ProcessLogFile(string file_name)
{
    LogFileName = file_name;

    apifile.open(LogFileName);//boost::iostreams::mapped_file_source apifile(declared globally)

    streamReader.open(apifile, std::ios::binary);//boost::iostreams::stream <boost::iostreams::mapped_file_source> streamReader(declared globally)

    streamoff Curr_Offset = 0;

    string read_line;

    int session_id = 0;

    int device_id = 0;

    while(!streamReader.eof())
    {
        \\COLLECT OFFSETS OF DIFFERENT SESSIONS
    }

    streamReader.close();
}

此功能有效,我得到了所需结构的偏移量。

现在调用此函数后,我调用了另一个函数,如下所示:

int GetSystemDetails()
{   
    streamReader.open(apifile, std::ios::binary);

    string read_line;

    getline(streamReader,read_line);

    cout << "LINE : " << read_line;

    streamReader.close();
}

我没有在read_line中获取任何数据。那个内存映射只针对单个函数吗?如何在不同的函数中使用相同的内存映射文件?

1 个答案:

答案 0 :(得分:11)

如果您只是按顺序读取文件,我同意人们质疑mmap的使用。

boost::mapped_file_source为设备建模。有两种方法可以使用这样的设备:

  1. 使用它(在尝试时使用data()
  2. 使用流包装器
  3. 1。使用原始设备源

    您可以使用mapped_file_source报告实际大小(m.data()+m.size())。

    让我们拿一个样本来计算行数:

    #include <boost/iostreams/device/mapped_file.hpp> // for mmap
    #include <algorithm>  // for std::find
    #include <iostream>   // for std::cout
    #include <cstring>
    
    int main()
    {
        boost::iostreams::mapped_file mmap("input.txt", boost::iostreams::mapped_file::readonly);
        auto f = mmap.const_data();
        auto l = f + mmap.size();
    
        uintmax_t m_numLines = 0;
        while (f && f!=l)
            if ((f = static_cast<const char*>(memchr(f, '\n', l-f))))
                m_numLines++, f++;
    
        std::cout << "m_numLines = " << m_numLines << "\n";
    }
    

    你可能会适应这一点。我有几个基于内存映射文件的更复杂的解析示例:


    2。将源设备包装在istream

    这为您提供了所有常见的基于流的c ++标准流操作,因此您可以像往常一样检测文件的结尾:

    #include <boost/iostreams/device/mapped_file.hpp> // for mmap
    #include <boost/iostreams/stream.hpp>             // for stream
    #include <algorithm>                              // for std::find
    #include <iostream>                               // for std::cout
    #include <cstring>
    
    int main()
    {
        using boost::iostreams::mapped_file_source;
        using boost::iostreams::stream;
        mapped_file_source mmap("test.cpp");
        stream<mapped_file_source> is(mmap, std::ios::binary);
    
        std::string line;
    
        uintmax_t m_numLines = 0;
        while (std::getline(is, line))
        {
            m_numLines++;
        }
    
        std::cout << "m_numLines = " << m_numLines << "\n";
    }