1

私は、2000 個のディレクトリを作成し、それぞれにファイル (わずか 10KB 程度のファイル) を配置するプログラムに取り組んでいます。mkdir を使用してディレクトリを作成し、ofstream (fopen も試しました) を使用して、ファイルをソリッド ステート ドライブに書き込みます (比較のために速度テストを行っています)。

コードを実行すると、ディレクトリは正常に作成されますが、ファイルは 1000 程度書き込まれた後に書き込みを停止します。ある種の過負荷の場合に備えて、各書き込みの前に遅延を入れてみました。また、ofstream の代わりに fopen を使用しようとしましたが、常に 1000 番目のファイル マークの周りでファイルの書き込みが停止します。

これは、ファイルを書き込んで終了し、失敗したファイルを通知するコードです。

fsWriteFiles.open(path, ios::app); 
if(!fsWriteFiles.is_open()) 
{
   cout << "Fail at point: " << filecount  << endl; 
   return 1;
}
fsWriteFiles << filecontent;
fsWriteFiles.close();

誰かがこれを経験したことがありますか、または理論を持っていますか?

完全なコードは次のとおりです。このコードは、乱数から 2 桁の 16 進数のディレクトリを作成し、次に乱数から 4 桁の 16 進数のディレクトリを作成し、そのディレクトリにファイルを保存します。1000 個のファイルを書き込んだ後、「fail at point」(私が追加した cout) で終了します。これは、ファイルを作成できないことを示していますが、ファイルが存在しないことは既に確認されているはずです。一番下の行から 2 番目にヒットした 0 で失敗することがあります (ファイルが既に存在する場合の else 句)。助けていただければ幸いです。作成しようとしている既存のファイルに関係していると思いますが、ファイルの存在チェックで何らかの形でずれてしまいました。ファイルの作成に失敗したときにエラー メッセージを表示する方法はありますか?

int main()
{
  char charpart1[3] = "";
  char charpart3[5] = "";

  char path[35] = "";
  int randomStore = 0;

  //Initialize random seed
  srand(time(NULL));
  struct stat buffer ;

  //Create output file streams
  ofstream fsWriteFiles;    
  ifstream checkforfile;

  //Loop X times
  int dircount = 0;
  while(dircount < 2000)
  {
    path[0] = '\0'; //reset the char array that holds the path

    randomStore = rand() % 255;
    sprintf(charpart1, "%.2x", randomStore);
    randomStore = rand() % 65535;
    sprintf(charpart3, "%.4x", randomStore);

    //Check if top level dir exists, create if not
    strcat(path, "fastdirs/");
    strcat(path, charpart1);
    DIR *pdir=opendir(path);

    //If the dir does not exist create it with read/write/search permissions for owner 
    // and group, and with read/search permissions for others
    if(!pdir)
      mkdir(path,  S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);

    //Check if 3rd level dir exists, create if not
    strcat(path, "/");
    strcat(path, charpart3);
    DIR *pdir3=opendir(path);

    if(!pdir3)
      mkdir(path,  S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);

    strcat(path, "/");
    strcat(path, charpart3);
    strcat(path, ".txt");
    //Write the file if it does not already exist
    checkforfile.open(path, fstream::in);

    if (checkforfile.is_open() != true)
    {
      fsWriteFiles.open(path, ios::app); 
      if(!fsWriteFiles.is_open()) 
      {
        cout << "Fail at point: " << dircount << "\n" << endl;
        return 1;
      }
      fsWriteFiles << "test";
      fsWriteFiles.flush();
      fsWriteFiles.close();

      dircount ++; //increment the file counter
    }
    else
    {
      cout << "ex";
      checkforfile.close();
    }
  } 
}
4

5 に答える 5

6

opendir() でディレクトリを開きますが、closedir() でそれらを閉じることはありません - そこにもリソース制限があると思います。

于 2009-08-18T13:50:00.080 に答える
1

ファイルを閉じますか?通常は 1024 であるファイル記述子の制限に達したようです。簡単なチェックのために、「ulimit -n 4096」を試して、プログラムを再度実行してください。

于 2009-08-18T10:34:54.037 に答える
1

投稿されたコードに明らかに問題があることはわかりませんが、誰かが大いに役立つ十分なコンテキストを示していません。

ただし、ofstream コンストラクター/デストラクタを使用してオープン/クローズを実行することにより、RAII を使用してファイルが確実に閉じられるようにしていただければ幸いです。

for (int i=0; i != MAX_FILES; ++i)
{     
  ofstream sWriteFiles(getFilePath(i), ios::app); 

  if (!fsWriteFiles.is_open()) 
  {
    cout << "Fail at point: " << filecount  << endl; 
    return 1;
  }

  fsWriteFiles << filecontent;
}

はい、ループを回るたびにストリームオブジェクトを「構築」していますが、このコードの方がはるかに保守しやすいと思います。

于 2009-08-18T11:01:04.870 に答える
1

boost::filesystemを認識していることを確認したいだけです。コードを大幅に簡素化できます。

#include "boost/filesystem.hpp"   // includes all needed Boost.Filesystem declarations
#include <iostream>               // for std::cout
using boost::filesystem;          // for ease of tutorial presentation;
                                  //  a namespace alias is preferred practice in real code

path my_path( "some_dir/file.txt" );

remove_all( "foobar" );
create_directory( "foobar" );
ofstream file( "foobar/cheeze" );
file << "tastes good!\n";
file.close();
if ( !exists( "foobar/cheeze" ) )
  std::cout << "Something is rotten in foobar\n";
于 2009-08-18T13:54:41.637 に答える
0

次のものがあります。

char charpart1[3] = "";
randomStore = rand() % 255;
sprintf(charpart1, "%.2x", randomStore);

x の代わりに "%.2f" 形式を使用するつもりでしたか? %.2x は引き続き "3ff3c083" を出力し、バッファをオーバーフローさせます。また、[0][.][2][3][\0] (たとえば) を書き込むため、%0.2f に切り替える場合は、おそらく charpart1 のサイズを 3 ではなく 5 にする必要があります。

于 2009-08-18T14:00:49.023 に答える