LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

DeleteFile error

Hi all, I  am occasionally experiencing a strange problem while trying to delete an existing file inside a callback function. Situation is as follows: during a long-lasting test (several weeks) I want to make a partial copy of test results to permit the user to examine them before the test is concluded. Here is my function:
 
void CVICALLBACK CopieAutomatiche (void *callbackData)
{
 int  i, br, line, size;
 int  d1H = 0, d2H = 0, orH = 0, error = 0;
 char msg[512], file[MAX_PATHNAME_LEN];
 
 for (br = 0, i = 1; i <= NumberOfFiles; i++) {
  // Get source file name
  fileDati (i, 0, file);
  // File doesn't exist or is empty: skip it
  if (!FileExists (file, &size) || !size) goto loop;
 
  orH = OpenFile (file, VAL_READ_ONLY, VAL_OPEN_AS_IS, VAL_ASCII);
  // Get destination file name
  fileDati (i, 1, file);
  d1H = OpenFile (file, VAL_WRITE_ONLY, VAL_APPEND, VAL_ASCII);
  // Second copy of data
  sprintf (file, "%s\\%s", dat, g.p[i].fd);
  d2H = OpenFile (file, VAL_WRITE_ONLY, VAL_APPEND, VAL_ASCII);
 
  // Scan files and take copies
  while (TRUE) {
   // Read from source file
   br = ReadLine (orH, msg, -1);
   if (br == -1) {    // Error!
    line = __LINE__;
    error = GetFmtIOError ();
    break;
   }
   if (br == -2) break;  // End of file
 
   // Write first copy
   if (WriteLine (d1H, msg, -1) == -1) {
    line = __LINE__;
    error = GetFmtIOError ();
    break;
   }
   // Write second copy
   if (WriteLine (d2H, msg, -1) == -1) {
    line = __LINE__;
    error = GetFmtIOError ();
    break;
   }
  }
  // Close files
  if (d1H) CloseFile (d1H);
  if (d2H) CloseFile (d2H);
  if (orH) CloseFile (orH);
 
  // Delete temporary files (only if no error found)
  if (!error) {
   fileDati (i, 0, file);
   error = DeleteFile (file);
   line = __LINE__;
  }
  if (error != 0) {
    // Warn the operator
  }
loop: ;
 }
 return;
}
The problem I am founding is some occasional error -6 (Access denied) in DeleteFile. This error is not constant but sometimes it happens and the file remains allocated to the program and it's not possible to delete it from the OS until I shut down my application.
I have checked the authorizations on the system: the user is the administrator of the system and it has full authorizations on files and folders.
 
I am wandering if the problem is something like disk cache that impede me to delete the file (that is: CloseFile returned without errors but the file isn't still closed when I immediately try to delete the files).
 
Environment: Windows XP SP2 - CVI 6.0.0
This error is only occurring in one of three installations of this application. In this case we have a machine with two disks in mirroring (may this be relevant?)
 
Anybody has some suggestions?


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 1 of 6
(4,543 Views)

It certainly sounds as though the disc mirroring is causing the difficulty, here. For my file based applications, I always use the ANSI specified file functions (not that I don't trust the CVI ones - I just like my code to be more portable) so I'm not that familiar with the CVI versions. In particular, I might be tempted to try a fflush() call just before any fclose() - I know this should not normally be necessary but I think this action would at least enforce the correct execution sequence and ensure that there was no queue of pending OS file/mirror operations which might be confusing the situation when you try to delete the file. Is there a CVI equivalent to implement such a file flush operation? I couldn't spot one quickly.

You could always rewrite the code using ANSI calls Smiley Surprised

JR

Edit - typo!

Message Edited by jr_2005 on 05-17-2007 11:12 AM

0 Kudos
Message 2 of 6
(4,543 Views)
Thanks jr for your suggestions, nevertheless I am not sure wether a fflush will help me solve my problem: CloseFile should flush all file contents to disk and return only after the write is concluded. At least, in the formatting and I/O library there exists a SetCommitMode function that, according to its documentation, should be used "to change whether CloseFile commits the file to disk before returning"; the default value should be 1, that is CloseFile returns only after the file has been effectively written to disk: can someone from NI confirm this assumption? If all that is true, the problem seems that the commit information is passed to applications before the complete writing to ALL disks is concluded (although I have no experience on multidisk machines with mirroring so I may talk nonsense Smiley Surprised 😞 may adding a simple delay between CloseFile and DeleteFIle help in this matter?
 
Back in DOS epoch ( Smiley Wink ) closing a file had always the effect to force writing to disk: in my experience I had several problems with a specific brand of PCs which was consistently loosing test data until I introduced a periodic close-open routine in my the code. As we all know very well, the more systems evolve the harder is to port usual simple tasks to the new environments Smiley Happy


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 3 of 6
(4,518 Views)

Hi Roberto,

 

I know it´s not an actual problem for you, but I have the same issue at this moment.

 

After file operation I close the file with fclose(), then

a.) call DeleteFile() -> I get an error code -6 (access denied)

b.) call remove() -> error code -1 (access denied)

 

so what can I do? I can´t leave the files on the Hard drive... Did you find out, how to avoid this? Additionally, in release mode I don´t get any message, the front panel just simply closes itself.

 

ciao

MB

0 Kudos
Message 4 of 6
(3,916 Views)

I am afraid I have no news for you Smiley Sad

 

I remember we tried adding delays or splitting the function in two sections executed in different times, but ultimately we decided to exclude that double-copy mechanism from the application as it was not consistent and difficutl to debug.

 

Nevertheless, you should be able to trap the return code from the functions and handle the error, at least emitting some message.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 5 of 6
(3,890 Views)

Hi Roberto,

 

I´m not sure if it´s a solution for you, but my problem is solved!

 

The problem was that the function GetFirstFile() returns the filename even if the file not yet completely closed by other application - regardless which application it is. The error code -1 (access denied) I have got either at fopen() or fclose(). In my case I poll a folder, and if I see the wanted file, I open it immediately. I just inserted a Delay(0.100) prior to call fopen(), and the problem seems to be disappeared. Without this line I can reproduce the failure.

 

It sounds logic: each application, which saves a file, creates the file first, fills it with data, then closes it. In my case I attempted to open a file too fast, so that the file has not yet been closed by the application, which creates the file.

 

With the 100ms delay the failure is away. Underneath you can see my code - already with the 100ms delay.

 

 

snap.jpg

Message 6 of 6
(3,865 Views)