我的经理告诉我创建一个测试,我需要测试某个特定单词是否存在于文件中。问题是文件可能非常大,如果测试运行很长时间,那么在回归测试期间它将失败。所以我想知道标准 C++ 中是否有任何方便的 API 可以快速告诉我这个词是否存在。我不想知道这个词的位置。该词位于文件开头附近的某个位置,但其确切位置未知。在这方面有什么帮助吗?谢谢你。
问问题
170 次
3 回答
3
如果文件没有特定的结构,除了包含单词(以任何顺序),唯一的解决方案是线性搜索,这意味着读取整个文件。如果您知道单词只能在开头附近,那么您只需搜索到该单词可以找到的最远点。
如果这还不够快,您要么必须以某种方式构造文件(排序等),要么必须加快阅读过程本身(例如 use mmap
)。
于 2013-03-11T10:12:37.690 回答
0
mmap
该文件,然后strnstr
它可能是最好的。除非您对文件结构有所了解,否则会限制您必须搜索的区域。
extern "C" {
#include <sys/mman.h>
#include <fcntl.h>
}
#include <cstring>
#include <cerrno>
#include <iostream>
int main(int argc, char* argv[]) {
// I don't check the arguments here, you should probably do that
// String to search for
char* search_string = argv[2];
// Open the file so we can map it
int fd = open(argv[1], O_RDONLY);
if (fd < 0) {
std::cout << "Open failed: " << strerror(errno) << std::endl;
return 1;
}
// Find the length of the file so we know how much to map
off_t len = lseek(fd, 0, SEEK_END);
if (len == -1) {
std::cout << "Seek failed: " << strerror(errno) << std::endl;
return 1;
}
// map the file into memory
char* file_contents = (char*)mmap(
NULL, len, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
if (file_contents == MAP_FAILED) {
std::cout << "map failed: " << strerror(errno) << std::endl;
return 1;
}
// We don't need the file open any more, we do need to unmap it later though
close(fd);
// Search for the string in the file here
char* found = strnstr(file_contents, search_string, len);
if (found == NULL)
std::cout << "String not found" << std::endl;
else
std::cout << "String found @ " << found - file_contents << std::endl;
munmap(file_contents, len);
}
于 2013-03-11T10:19:05.470 回答
0
内存映射文件访问允许您直接访问文件的某些部分,而无需将其加载到内存中。
据我所知,Qt 也提供内存映射,而 C++ 标准库也没有。
您还可以使用操作系统的本机 API。mmap
对于 UNIX,CreateFileMapping
对于 Windows。
于 2013-03-11T10:45:16.067 回答