我发布了一个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)已被内存映射,因此我可以遍历数据指针并过滤掉行。我这样做正确吗?
如果是这样,解析行的有效方法是什么?
答案 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;
}
我希望这对您有帮助