检索存储在缓冲区中的文件数据
Retrieving File Data Stored in Buffer
我是论坛的新手,但不是这个网站的新手。数周以来,我一直在寻找如何使用 C++ 11 快速处理大型数据文件的方法。我正在尝试使用一个成员函数来捕获跟踪文件名、打开并处理数据。跟踪文件包含200万行数据,每行由read/write操作和十六进制地址构成:
r abcdef123456
但是,对于包含那么多数据的文件,我需要快速读入并解析这 2 个值。我第一次尝试读取文件如下:
void getTraceData(string filename)
{
ifstream inputfile;
string file_str;
vector<string> op, addr;
// Open input file
inputfile.open(filename.c_str());
cout << "Opening file for reading: " << filename << endl;
// Determine if file opened successfully
if(inputfile.fail())
{
cout << "Text file failed to open." << endl;
cout << "Please check file name and path." << endl;
exit(1);
}
// Retrieve and store address values and operations
if(inputfile.is_open())
{
cout << "Text file opened successfully." << endl;
while(inputfile >> file_str)
{
if((file_str == "r") || (file_str == "w"))
{
op.push_back(file_str);
}
else
{
addr.push_back(file_str);
}
}
}
inputfile.close();
cout << "File closed." << endl;
}
成功了,它 运行,并读入了文件。不幸的是,程序花了 8 分钟才 运行 并读取文件。我将第一个程序修改为第二个程序,以尝试更快地读取文件。它做到了,在几分之一秒内将文件读入缓冲区,而不是 8 分钟。使用 ifstream:
void getTraceData()
{
// Setup variables
char* fbuffer;
ifstream ifs("text.txt");
long int length;
clock_t start, end;
// Start timer + get file length
start = clock();
ifs.seekg(0, ifs.end);
length = ifs.tellg();
ifs.seekg(0, ifs.beg);
// Setup buffer to read & store file data
fbuffer = new char[length];
ifs.read(fbuffer, length);
ifs.close();
end = clock();
float diff((float)end - (float)start);
float seconds = diff / CLOCKS_PER_SEC;
cout << "Run time: " << seconds << " seconds" << endl;
delete[] fbuffer;
}
但是当我添加代码的解析部分,获取每一行,并逐行解析缓冲区内容以将两个值存储在两个单独的变量中时,程序在 while 循环中静默退出包含来自缓冲区的 getline:
void getTraceData(string filename)
{
// Setup variables
char* fbuffer;
ifstream ifs("text.txt");
long int length;
string op, addr, line;
clock_t start, end;
// Start timer + get file length
start = clock();
ifs.seekg(0, ifs.end);
length = ifs.tellg();
ifs.seekg(0, ifs.beg);
// Setup buffer to read & store file data
fbuffer = new char[length];
ifs.read(fbuffer, length);
ifs.close();
// Setup stream buffer
const int maxline = 20;
char* lbuffer;
stringstream ss;
// Parse buffer data line-by-line
while(ss.getline(lbuffer, length))
{
while(getline(ss, line))
{
ss >> op >> addr;
}
ss.ignore( strlen(lbuffer));
}
end = clock();
float diff((float)end - (float)start);
float seconds = diff / CLOCKS_PER_SEC;
cout << "Run time: " << seconds << " seconds" << endl;
delete[] fbuffer;
delete[] lbuffer;
}
我想知道,一旦我的文件被读入缓冲区,我该如何检索它并将其存储到变量中?为了增加价值,我的基准时间不到 2 分钟。读取和处理数据文件。但现在,我只专注于输入文件,而不是程序的其余部分或它 运行 所在的机器(代码可移植到其他机器)。语言是 C++ 11,OS 是一台 Linux 计算机。抱歉发帖太长了。
您的 stringstream ss
与 fbuffer
完全没有关联。您正在尝试从空的 stringstream
getline
,因此没有任何反应。试试这个:
string inputedString(fbuffer);
istringstream ss(fbuffer);
在ss.getline(lbuffer, length)
之前,请为lbuffer
分配内存。
其实你可以直接把你的文件读成一个字符串来避免复制构造。检查此 Reading directly from an std::istream into an std::string .
最后但同样重要的是,由于您的 vector
很大,您最好在 push_back
一项一项之前为它预留足够的 space 。当向量达到其容量时,尝试将另一个项目 push_back
放入其中将导致重新分配和复制所有先前的项目,以确保连续存储。数以百万计的项目将使这种情况发生很多次。
我是论坛的新手,但不是这个网站的新手。数周以来,我一直在寻找如何使用 C++ 11 快速处理大型数据文件的方法。我正在尝试使用一个成员函数来捕获跟踪文件名、打开并处理数据。跟踪文件包含200万行数据,每行由read/write操作和十六进制地址构成:
r abcdef123456
但是,对于包含那么多数据的文件,我需要快速读入并解析这 2 个值。我第一次尝试读取文件如下:
void getTraceData(string filename)
{
ifstream inputfile;
string file_str;
vector<string> op, addr;
// Open input file
inputfile.open(filename.c_str());
cout << "Opening file for reading: " << filename << endl;
// Determine if file opened successfully
if(inputfile.fail())
{
cout << "Text file failed to open." << endl;
cout << "Please check file name and path." << endl;
exit(1);
}
// Retrieve and store address values and operations
if(inputfile.is_open())
{
cout << "Text file opened successfully." << endl;
while(inputfile >> file_str)
{
if((file_str == "r") || (file_str == "w"))
{
op.push_back(file_str);
}
else
{
addr.push_back(file_str);
}
}
}
inputfile.close();
cout << "File closed." << endl;
}
成功了,它 运行,并读入了文件。不幸的是,程序花了 8 分钟才 运行 并读取文件。我将第一个程序修改为第二个程序,以尝试更快地读取文件。它做到了,在几分之一秒内将文件读入缓冲区,而不是 8 分钟。使用 ifstream:
void getTraceData()
{
// Setup variables
char* fbuffer;
ifstream ifs("text.txt");
long int length;
clock_t start, end;
// Start timer + get file length
start = clock();
ifs.seekg(0, ifs.end);
length = ifs.tellg();
ifs.seekg(0, ifs.beg);
// Setup buffer to read & store file data
fbuffer = new char[length];
ifs.read(fbuffer, length);
ifs.close();
end = clock();
float diff((float)end - (float)start);
float seconds = diff / CLOCKS_PER_SEC;
cout << "Run time: " << seconds << " seconds" << endl;
delete[] fbuffer;
}
但是当我添加代码的解析部分,获取每一行,并逐行解析缓冲区内容以将两个值存储在两个单独的变量中时,程序在 while 循环中静默退出包含来自缓冲区的 getline:
void getTraceData(string filename)
{
// Setup variables
char* fbuffer;
ifstream ifs("text.txt");
long int length;
string op, addr, line;
clock_t start, end;
// Start timer + get file length
start = clock();
ifs.seekg(0, ifs.end);
length = ifs.tellg();
ifs.seekg(0, ifs.beg);
// Setup buffer to read & store file data
fbuffer = new char[length];
ifs.read(fbuffer, length);
ifs.close();
// Setup stream buffer
const int maxline = 20;
char* lbuffer;
stringstream ss;
// Parse buffer data line-by-line
while(ss.getline(lbuffer, length))
{
while(getline(ss, line))
{
ss >> op >> addr;
}
ss.ignore( strlen(lbuffer));
}
end = clock();
float diff((float)end - (float)start);
float seconds = diff / CLOCKS_PER_SEC;
cout << "Run time: " << seconds << " seconds" << endl;
delete[] fbuffer;
delete[] lbuffer;
}
我想知道,一旦我的文件被读入缓冲区,我该如何检索它并将其存储到变量中?为了增加价值,我的基准时间不到 2 分钟。读取和处理数据文件。但现在,我只专注于输入文件,而不是程序的其余部分或它 运行 所在的机器(代码可移植到其他机器)。语言是 C++ 11,OS 是一台 Linux 计算机。抱歉发帖太长了。
您的 stringstream ss
与 fbuffer
完全没有关联。您正在尝试从空的 stringstream
getline
,因此没有任何反应。试试这个:
string inputedString(fbuffer);
istringstream ss(fbuffer);
在ss.getline(lbuffer, length)
之前,请为lbuffer
分配内存。
其实你可以直接把你的文件读成一个字符串来避免复制构造。检查此 Reading directly from an std::istream into an std::string .
最后但同样重要的是,由于您的 vector
很大,您最好在 push_back
一项一项之前为它预留足够的 space 。当向量达到其容量时,尝试将另一个项目 push_back
放入其中将导致重新分配和复制所有先前的项目,以确保连续存储。数以百万计的项目将使这种情况发生很多次。