使用mmap

时间:2018-12-03 12:03:46

标签: c++ mmap

我发布了一个question,它通过跳过特定的行与更快地读取文件有关,但这似乎与标准c ++ api不太匹配。

我进行了更多的研究,并了解了哪些内存映射文件可用于此类情况。有关内存映射文件的详细信息为here

总而言之,

假设文件(file.txt)如下:

A quick brown fox 
// Blah blah
// Blah blah
jumps over the little lazy dog

然后在代码中打开文件,将其读取为内存映射文件,然后遍历char *指针的内容,跳过文件指针本身。想要在得出结论之前先尝试一下。我的代码的骨架如下所示:

struct stat filestat;
FILE *file = fopen("file.txt", "r");
if (-1 == fstat(fileno(file), &filestat)) {
  std::cout << "FAILED with fstat" << std::endl;
  return FALSE;
} else {
  char* data = (char*)mmap(0, filestat.st_size, PROT_READ, MAP_PRIVATE, fileno(file), 0);
  if (data == 0) {
    std::cout << "FAILED " << std::endl;
    return FALSE;
  }
  // Filter out 'data'
  // for (unsigned int i = 0; i < filestat.st_size; ++i) {
  //   Do something here..
  // }

  munmap(data, filestat.st_size);
  return TRUE;
}   

在这种情况下,我想捕获不是以//开头的行。由于此文件(file.txt)已被内存映射,因此我可以遍历数据指针并过滤掉行。我这样做正确吗?

如果是这样,解析行的有效方法是什么?

1 个答案:

答案 0 :(得分:0)

从任何地方读取所选行并将其复制到C ++算法可以完成的任何事情。

您可以使用std::copy_if。如果谓词为true,它将把数据从任何源复制到任何目的地。

我向您展示了一个简单的示例,该示例复制文件中的数据并跳过以“ //”开头的所有行。结果将被放入向量中。

这是一个调用一个函数的语句。因此,这是一种经典的班轮。

出于调试目的,我将结果打印到控制台。

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <string>
#include <fstream>

using LineBasedTextFile = std::vector<std::string>;

class CompleteLine {    // Proxy for the input Iterator
public:
    // Overload extractor. Read a complete line
    friend std::istream& operator>>(std::istream& is, CompleteLine& cl) { std::getline(is, cl.completeLine); return is; }
    // Cast the type 'CompleteLine' to std::string
    operator std::string() const { return completeLine; }
protected:
    // Temporary to hold the read string
    std::string completeLine{};
};

int main()
{
    // Open the input file
    std::ifstream inputFile("r:\\input.txt");
    if (inputFile)
    {
        // This vector will hold all lines of the file
        LineBasedTextFile lineBasedTextFile{};
        // Read the file and copy all lines that fullfill the required condition, into the vector of lines
        std::copy_if(std::istream_iterator<CompleteLine>(inputFile), std::istream_iterator<CompleteLine>(), std::back_inserter(lineBasedTextFile), [](const std::string & s) {return s.find("//") != 0; });
        // Print vector of lines
        std::copy(lineBasedTextFile.begin(), lineBasedTextFile.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
    }
    return 0;
}

我希望这对您有帮助

相关问题