4

我在使用我的程序删除/覆盖文件时遇到问题,该程序也被我的程序使用(读取)。问题似乎是因为我的程序正在从文件(output.txt)中读取数据,它使文件处于“使用中”状态,这使得无法删除或覆盖文件。

我不明白为什么文件保持“使用中”,因为我在使用 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
    }
}

很抱歉再次使用 pre 但我没有得到这个网站的格式:(

4

5 回答 5

1

您的代码中可能还有其他地方您不调用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);

告诉我们是否有帮助;

于 2011-01-12T09:08:30.410 回答
1

是否是由于已达到最大磁盘空间并且文件流缓冲区中仍有数据?fclose 文件流会刷新它(将所有数据写入缓冲区),由于达到最大磁盘空间,写入操作将失败。

我建议您通过在 fopen() 之后直接调用 fclose() 来缩小问题的范围。如果成功,则说明 fclose() 和 fopen() 之间的代码有问题。

于 2011-01-12T09:43:46.163 回答
0

CRT 或操作系统可能仍在使用该文件 - 例如,操作系统可能会缓冲对磁盘的写入。fflush() 只会刷新 CRT 缓冲区,而不是操作系统缓冲区。

于 2011-01-12T09:40:02.560 回答
0

只是在这里在黑暗中拍摄...

里面是什么runProgram()?该函数是否等到程序完成后再返回?我想知道正在写入数据的程序是否实际上仍在运行……从这里很难判断,但我想我会把它扔掉!

于 2011-01-12T09:54:45.307 回答
-1

在阅读了所有答案和评论后,我想不出任何 OP 问题的原因。

这是多线程还是可重入例程?

如果在同一个文件上两次 fopen 和 fclose 两次会发生什么?这可能是问题的原因吗?

在这个想法中,我建议再进行两次检查。

  • printf all fopen/fclose 调用
  • fclose 后将文件变量重置为 NULL

f = fopen("", ""); printf("fopen => %p", f);
f关闭(f);printf("fclose => %p", f); f = 0;

如果您不方便使用 printf 调试,您可以使用 OutputDebugString。

extern void __stdcall OutputDebugStringA(const char*)(仅限 MS VC)

于 2011-01-12T11:44:10.410 回答