2011-01-12 9 views
4

自分のプログラムで使用されている(読み込み中の)プログラムを使用してファイルの削除/上書きに問題があります。問題は、私のプログラムがファイル(output.txt)からデータを読み込んでいるために、ファイルを「使用中」の状態にしてしまい、ファイルの削除や上書きが不可能になっているようです。fclose()でファイルを閉じてもファイルはまだ使用中です

fclose()で使用した後にファイルを閉じるため、ファイルが「使用中」のままになっている理由を理解できません。

これは私のコードです:

bool bBool = true 

while(bBool){ 
    //Run myprogram.exe tot generate (a new) output.txt 

    //Create file pointer and open file 
    FILE* pInputFile = NULL; 
    pInputFile = fopen("output.txt", "r"); 
    // 
    //then I do some reading using fscanf() 
    // 
    //And when I'm done reading I close the file using fclose() 
    fclose(pInputFile); 

    //The next step is deleting the output.txt 
    if(remove("output.txt") == -1){ 
    //ERROR 
    }else{ 
    //Succesfull 
    } 
} 

は、私は、ファイルを閉じるために)(fcloseを使用しますが、私のプログラムが完全にシャットダウンされるまで、ファイルは私のプログラムで使用中のまま。

ファイルを削除して上書きできるようにするには、どのような方法がありますか?

実際には、私のコードは終わりのないループではありません。 )

ありがとうございます!

マルコ

更新

のようにも「使用中」のファイルを生成し、自分のコードの一部を尋ねます。これはループではなく、この関数はmain()から呼び出されています。ここ

は、コードの一部である:

int iShapeNr = 0; 

void firstRun() 
{ 
    //Run program that generates output.txt 
    runProgram(); 

    //Open Shape data file 
    FILE* pInputFile = NULL; 
    int iNumber = 0; 
    pInputFile = fopen("output.txt", "r"); 

    //Put all orientations of al detected shapes in an array 
    int iShapeNr = 0; 
    int iRotationBuffer[1024];//1024 is maximum detectable shapes, can be changed in RoboRealm 
    int iXMinBuffer[1024]; 
    int iXMaxBuffer[1024]; 
    int iYMinBuffer[1024]; 
    int iYMaxBuffer[1024]; 

    while(feof(pInputFile) == 0){  
     for(int i=0;i<9;i++){ 
      fscanf(pInputFile, "%d", &iNumber); 
      fscanf(pInputFile, ","); 
      if(i == 1) { 
       iRotationBuffer[iShapeNr] = iNumber; 
      } 
      if(i == 3){//xmin 
       iXMinBuffer[iShapeNr] = iNumber; 
      } 
      if(i == 4){//xmax 
       iXMaxBuffer[iShapeNr] = iNumber; 
      } 
      if(i == 5){//ymin 
       iYMinBuffer[iShapeNr] = iNumber; 
      } 
      if(i == 6){//ymax 
       iYMaxBuffer[iShapeNr] = iNumber; 
      } 
     } 
     iShapeNr++; 
    } 
    fflush(pInputFile); 
    fclose(pInputFile); 

} 

whileループは、ファイルを解析します。 output.txtとは、9つの変数のセットが含まれている、セットの数は9

のセットでoutput.txtとは、例えば含まれている可能性が常に不明だが:0,1,2,3,4,5,6,7 、8,8,7,6,5,4,1,2,3,0

更新2

コード:

void runProgram(){ 
    //Check if output.txt exists, if so delete it 
    if(fileExists("output.txt") == 1){ 
     //Delete output.txt 
     if(remove("output2.txt") == -1){ 
      //errormessage 
     }else{ 
      //succesfull 
     } 
    } 
    //start program 
    ShellExecute(NULL, TEXT("open"), TEXT("program.exe"), NULL, NULL, SW_SHOWMAXIMIZED); 

    while(fileExists("output.txt") == 0); 

    //Close program 
    int iCheck = system("taskkill /IM program.exe"); 
    if(iCheck != 0){ 
     //error could not shut down 
    } 
} 

再び前を使用して申し訳ありませんが、私はドン」このサイトのフォーマットを取得する:(

+1

あなたは何が悪かったのかについての診断を得るためにはstrerror/perrorはを使用していますか?あなたはどんなOSですか? –

+0

fclose()する前にファイルをfflush()しようとしましたか? – Bart

+0

@Bart、それは必要ではありません、 'flcose()'がそれを処理します。 @Marcoは、@Henno Brandsmaが言っているように、 'errno'を検査し、それが何であるかを見ると、これはあなたにいくつかの手がかりを与えるかもしれません。副次的に、これはC++でタグ付けされています。なぜIOストリームを使用していませんか? – Nim

答えて

0

fcloseに電話をかけずにコードを漏らしている場所にコード内の他の場所があります。このコードでも、fopenとfclose(またはreturn文またはcontinue文など)の間にエラーが発生すると、ファイルがリークします。 RAIIイディオムに切り替えてください。

編集:はあなたのコードにこれを含める:

struct PoorMansFile { 
    FILE *_file; 
    PoorMansFile(const char* str1, const char* str2) : _file(fopen(str1,str2)) {} 
    ~PoorMansFile() { if(_file) fclose(_file); } 
    operator FILE*() const { return _file; } 
}; 
int fclose(PoorMansFile& file) 
{ 
    if(!file) 
     return 0; 

    int t = fclose(file._file); 
    file._file = 0; 
    return t; 
} 

とでそれぞれ

FILE* file = NULL; 
file = fopen(str1, str2); 

を置き換える:

PoorMansFile file(str1, str2); 

それは場合に役立ちます教えてください。

+0

私は自分のコードをチェックしましたが、ファイルを開くたびに閉じます。 RAAIイディオムはどういう意味ですか? – Marco

+0

"私は自分のコードをチェックしましたが、ファイルを開くたびに閉じるようにしています。"これはとても素朴な文です。 [RAII](http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization)や良いC++の本を参照してください。基本的にstd :: fstreamに切り替えます。 – ybungalobill

+0

@Marco、RAIIは* R * esource * A * quisition * I * s * I *の初期化を表します。基本的には、リソースを持つオブジェクトがあれば、それらのリソースを使うだけで十分です。したがって、ybungalobillは 'std :: fstream'を使うことを提案しています。 –

0

ファイルがCRTまたはOSによって引き続き使用されている可能性があります。たとえば、OSがディスクへの書き込みをバッファリングする可能性があります。 fflush()はOSバッファではなくCRTバッファのみをフラッシュします。

+0

これを解決する方法についてのご意見はありますか? – Marco

+0

@Marco:それはOS固有のものです。 – Puppy

1

最大ディスク容量に達したためファイルにデータが残っているかどうか ストリームバッファ。ファイル・ストリームをフラッシュして(バッファー内のすべてのデータを書き込む)、最大ディスク・スペースに達したため書き込み操作は失敗します。

fopen()の直後にfclose()を呼び出すと、問題の範囲を絞り込むことをお勧めします。 成功した場合は、fclose()とfopen()の間のコードに問題があります。ここでは暗闇の中でだけでショット

+0

彼は読み取りモードでファイルを開いています。 –

+0

ディスク容量に関しては、十分な容量(34GB)があります。私はfopen()の直後にfclose()を試みます。 – Marco

+0

fopen()の直後にfclose()を実行すると同じ問題が発生し、間にコードが間違っていることはありません。 – Marco

0

は...

内部runProgram()は何ですか?この関数は、プログラムが終了するまで待ってから返されますか? 書いているプログラムがのデータであるのは、実際にはまだ実行中です...ここからは伝えにくいですが、そこに捨てると思っていました!

+0

runProgram()は、プログラムを起動するためにShellExecute()を使用しています。このプログラムはoutput.txtを生成し、プログラムが終了できるかどうかを確認する最も簡単な方法(system( "taskkill"))は、output.txtが存在するかどうかをチェックすることです(プログラムは生成後にシャットダウンされません。 。そして、問題が今どこにあるのか。最初のrun therはoutput.txtではないので、すべてが正常になります。しかし、最初の実行後に、2番目の実行をOKにするためにoutput.txtを削除する必要があります。しかし、output.txtは使用中であるため削除できません。 – Marco

+0

@Marco、ファイルが存在するという理由だけで、ファイルが閉じているか、プログラムの実行が終了しているわけではありません。 –

+0

もちろん、ファイルは開いているので、最初にShellExecute()を実行するとファイルがあなたのためにそこにあるファイルを構築するプログラム。あなたがそれを読んですぐに、ライティングプログラムはまだ動作しています。おそらくあなたがあなたがそれを取り除くことができないようにあなたが呼んでいるプログラムによって使用されている間、読書プログラムはファイルの終わりに当たるでしょう。 これを試してみてください: a)output.txtファイルを作成するプログラムが 'o.txt'ファイルを開き、そのファイルに書き込みます。 b)プログラムが終了したら、 'o.txt'ファイルを閉じて、 'output.txt'に名前を変更します。 c)プログラムshoulを読んでいたら、それを削除するのに問題はありません! –

-1

すべての回答とコメントを読んだ後、私はOPの問題の理由を考えることができませんでした。

マルチスレッドまたはリエントラントルーチンですか?

同じファイルでfopenを2回、fcloseを2回実行するとどうなりますか?これが問題の原因になるのでしょうか?

この考えで私はもう2つの点検をお勧めします。

  • のprintf FCLOSE

のF =用のfopen( "を"、 "")NULLにファイル変数をリセットした後、全てのfopen/FCLOSE

  • を呼び出します。 printf( "fopen =>%p"、f);
    fclose(f); printf( "fclose =>%p"、f); f = 0;

    printfデバッグに不都合がある場合は、OutputDebugStringを使用できます。

    extern void __stdcall OutputDebugStringA(const char*)(のみMS VC)

  • 関連する問題