【问题标题】:Retrieving File Data Stored in Buffer检索存储在缓冲区中的文件数据
【发布时间】:2015-03-06 05:45:35
【问题描述】:

我是论坛的新手,但不是这个网站的新手。我一直在寻找如何使用 C++ 11 快速处理大型数据文件的几个星期。我正在尝试使用一个函数来捕获跟踪文件名、打开和处理数据。跟踪文件包含 200 万行数据,每行由一个读/写操作和一个十六进制地址构成:

r abcdef123456

但是,对于包含这么多数据的文件,我需要快速读取并解析这两个值。我第一次尝试读取文件如下:

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;
}

但是当我添加代码的解析部分以获取每一行并逐行解析缓冲区内容以将两个值存储在两个单独的变量中时,程序会在包含 getline 的 while 循环处静默退出来自缓冲区:

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,操作系统是 Linux 计算机。抱歉发了这么久。

【问题讨论】:

  • 你将数据读入fbuffer,然后你不会对读入的数据做任何事情!

标签: c++ performance buffer ifstream large-files


【解决方案1】:

您的 stringstream ssfbuffer 根本没有关联。你正试图从一个空的stringstreamgetline,因此没有任何反应。试试这个:

string inputedString(fbuffer);
istringstream ss(fbuffer);

ss.getline(lbuffer, length)之前,请为lbuffer分配内存。

其实你可以直接将你的文件读入一个字符串来避免复制构造。检查这个Reading directly from an std::istream into an std::string

最后但同样重要的是,由于您的vector 相当大,您最好在push_back 之前为它预留足够的空间@ 一项一项。当一个向量达到其容量时,尝试将另一个项目push_back 放入其中将导致重新分配和复制所有先前的项目,以确保连续存储。数以百万计的项目将使这种情况发生很多次。

【讨论】:

  • 非常感谢@JingLi!我阅读文章链接并使用方法:'ifstream file(“text.txt)'直接读取文件。我没有意识到我实际上是在复制文件内容。我的程序可以工作,并且它读取每个线快!:-D 仍在学习如何使用 Stack Overflow 语法结构来发布程序代码。
猜你喜欢
  • 2021-10-24
  • 2015-01-22
  • 1970-01-01
  • 1970-01-01
  • 2019-01-27
  • 2018-12-17
  • 1970-01-01
  • 1970-01-01
  • 2017-10-19
相关资源
最近更新 更多