C / C ++系统以便携方式更改最大打开文件数

时间:2011-05-19 14:04:17

标签: c++ file-io matrix operating-system temporary-files

我有一个转换非常大的矩阵的C ++程序。矩阵太大而无法保存在内存中,因此我将每列写入单独的临时文件,然后在处理完整个矩阵后连接临时文件。但是,我现在发现我遇到了打开临时文件太多的问题(即操作系统不允许我打开足够的临时文件)。是否有系统可移植方法来检查(并希望更改)允许的最大打开文件数?

我意识到我可以关闭每个临时文件并仅在需要时重新打开,但我担心这样做会对性能产生影响。

我的代码如下工作(伪代码 - 不保证可以正常工作):

int Ncol=5000; // For example - could be much bigger.
int Nrow=50000; // For example - in reality much bigger.

// Stage 1 - create temp files
vector<ofstream *> tmp_files(Ncol);  // Vector of temp file pointers.
vector<string> tmp_filenames(Ncol);  // Vector of temp file names.
for (unsigned int ui=0; ui<Ncol; ui++)
{
    string filename(tmpnam(NULL));  // Get temp filename.
    ofstream *tmp_file = new ofstream(filename.c_str());
    if (!tmp_file->good())
         error("Could not open temp file.\n"); // Call error function
    (*tmp_file) << "Column" << ui;
    tmp_files[ui] = tmp_file;
    tmp_filenames[ui] = filename;
 }

 // Stage 2 - read input file and write each column to temp file
 ifstream input_file(input_filename.c_str());
 for (unsigned int s=0; s<Nrow; s++)
 {
       int input_num;
       ofstream *tmp_file;
       for (unsigned int ui=0; ui<Ncol; ui++)
       {
           input_file >> input_num;
           tmp_file = tmp_files[ui];          // Get temp file pointer
           (*tmp_file) << "\t" << input_num;  // Write entry to temp file.
       }
 }
 input_file.close();

 // Stage 3 - concatenate temp files into output file and clean up.
 ofstream output_file("out.txt");
 for (unsigned int ui=0; ui<Ncol; ui++)
 {
      string tmp_line;
      // Close temp file
      ofstream *tmp_file = tmp_files[ui];
      (*tmp_file) << endl;
      tmp_file->close();

      // Read from temp file and write to output file.
      ifstream read_file(tmp_filenames[ui].c_str());
      if (!read_file.good())
            error("Could not open tmp file for reading."); // Call error function
      getline(read_file, tmp_line);
      output_file << tmp_line << endl;
      read_file.close();

      // Delete temp file.
      remove(tmp_filenames[ui].c_str());
 }
 output_file.close();

非常感谢提前!

亚当

5 个答案:

答案 0 :(得分:2)

至少有两个限制:

  • 操作系统可能会施加限制;在Unix(sh,bash和类似shell)中,使用ulimit更改限制,在sysadmin允许的范围内
  • C库实现也可能有限制;您可能需要重新编译库以更改

更好的解决方案是避免有这么多打开的文件。在我自己的一个程序中,我编写了一个围绕文件抽象的包装器(这是在Python中,但原理在C中是相同的),它跟踪每个文件中的当前文件位置,并根据需要打开/关闭文件,保留一组当前打开的文件。

答案 1 :(得分:1)

没有可移植的方法来更改打开文件的最大数量。这样的限制往往是由操作系统强加的,因此也是特定于操作系统的。

您最好的办法是减少任何时候打开的文件数量。

答案 2 :(得分:1)

您可以将输入文件规范化为临时文件,以使每个条目占用相同数量的字符。您甚至可以考虑将该临时文件保存为二进制文件(每个数字使用4/8字节而不是每个十进制数字1个字节)。这样,您可以从矩阵中的坐标计算文件中每个条目的位置。然后,您可以通过std::istream::seekg访问特定条目,而不必担心打开文件数量的限制。

答案 3 :(得分:0)

如何制作1个大文件而不是许多小型临时文件? Seek是一项廉价的操作。无论如何,你的列应该都是相同的大小。您应该能够将文件指针放在需要它的地方。

 // something like...

 column_position = sizeof(double)*Nrows*column ;
 is.seekg(column_position) ;
 double column[Nrows] ;
 for( i = 0 ; i < Nrows ; i++ )
    is >> column[i] ;

答案 4 :(得分:0)

“矩阵太大而无法容纳在内存中”。但是,矩阵很可能适合您的地址空间。 (如果矩阵不适合2 ^ 64字节,你需要一个非常令人印象深刻的文件系统来保存所有这些临时文件。)所以,不要担心临时文件。让操作系统处理交换到磁盘的工作方式。您只需要确保以交换友好的方式访问内存。在实践中,这意味着您需要具有一些参考地点。但是使用16 GB的RAM,你可以有大约400万页的RAM映射。如果你的columsn数量明显小于那个,那么应该没有问题。

(不要为此使用32位系统;这不值得痛苦)