A folder is not deleted if it contains unclosed files - page 6

 
I wondered what it was all about. When I'm free, I'll look into it... Of course, I would like a more concise statement of the task
 
Vladimir Karputov:

Please continue - as long as you write in the fascinating genre of "fiction". Hopefully by about page 40 you'll have moved on to technical literature.

The mistake is implicit. It's hard to give more technical details at the moment.
 
Реter Konow:

I have all files erased even without explicitly closing them. Erased because I didn't create them and they were previously inside the Files folder.

The point is that in order to erase a file, we need its handle. However, if we didn't create this file, but only put it into Files folder, we can't get its handle, and therefore we can't close it with FileClose().

At the same time, we can still copy or erase it. However, the folder cannot be deleted after that either programmatically or manually. Manually only after restarting the terminal.

I will try to reproduce the problem more clearly later, with illustrative examples.

The code just has to be complete. If the file is open, it must be closed before computer shutdown or closing of MT4/5. And the handle preferably must be accessible from any place of the program. This is my opinion. Better yet, close the file immediately after you perform a read/write operation with it or even if you don't have to do anything with it.

The example documentation seems to show how not to do it.

It is also very important to remember that when writing to a file, the written file can only be read by flushing all data remaining in the file I/O buffer to disk using FileFlush or by closing the file. Closing the file will force a reset of the data to disk.

Summary: If you open a file, don't forget to close it. And the file handle will not be lost.

Документация по MQL5: Файловые операции / FileFlush
Документация по MQL5: Файловые операции / FileFlush
  • www.mql5.com
Файловые операции / FileFlush - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Alexey Viktorov:

The code simply needs to be complete. If a file is open, it should be closed before shutting down the computer or closing MT4/5. And the handle, preferably, should be accessible from any place in the program. This is IMHO. Better yet, close the file immediately after the read/write operation with it or even if you didn't have to do anything with it.

The example documentation seems to show how not to do it.

It is also very important to remember that when writing to a file, the written file can only be read by flushing all data remaining in the file I/O buffer to disk using FileFlush or by closing the file. Closing the file will force a reset of the data to disk.

Summary: If you open a file, don't forget to close it. And the file handle will not be lost.

Once again, I can close a file created by my program using FileClose() function - I have its handle.

I cannot close a file created by someone else, but existing in the Files folder, because I do not have a handle to it.

If I copy file, which was not created by me (not my program), then I can not close it after copying with FileClose() function (no handle), BUT I can erase it.

Maybe that's why folders with copied and deleted files are not deleted by FolderClean() function. Probably, because they were not closed after they were copied.

BUT THEY CANNOT BE CLOSED BECAUSE THEY DON'T HAVE A HANDLE!

:)))

 

Questions for developers:

1. how do I get the handle of the file that was created in the Files folder before loading the script?

2. Could the problem of deleting folders using FolderClean(), after erasing files in them that were previously copied to another folder and not closed after copying (because there is no handle), have the above cause?

 
Реter Konow:

Questions for developers:

1. how do I get the handle of the file that was created in the Files folder before loading the script?

2. Could the problem of deleting folders using the FolderClean() function, after erasing files in them that were previously copied into another folder and not closed after copying (because there is no handle), have the above reason?


This is sort of the basics of the OS. If an application has opened a file for writing, neither that file nor the folder containing it can be deleted. Try opening a file in Word and then using the OS's tools to delete the folder it's in. What will happen? You won't be able to, because you won't have access to it.

But you can get the file handle. But what good would such an action do? After all, if the file is opened by another application, you will see the previous statement. We will only get a handle which is valid in our application.

 
Ihor Herasko:

This is sort of the basics of the OS. If an application has opened a file for writing, neither the file nor the folder containing it can be deleted. Try opening a file in Word and then using the OS to delete the folder it is in. What will happen? You won't be able to, because you won't have access to it.

Well, you can get the file handle. But what good would such an action do? After all, if the file is opened by another application, you will see the previous statement. And we can only get a handle which is valid in our particular application.

The file is opened by my application (file navigator) to be overwritten to another folder.

After overwriting I need to close the file but I can't - (no handle) so I just erase the file.

There is no handle because the file was created unknown when and unknown by whom.

At the same time, the file exists inside the Files folder and can be copied to another folder and then erased.

But after copying, the file cannot be closed. There is no handle.

This is probably why further erasing of folders FolderClean() with erased files, does not work.


Question: how do I get the handle of this file into the MQL program?

 

This seems to be a problem not yet faced in the community... :)

OK, I'll think of something.

I always do.)

 

Debunking myths.

So, terminal data on the operating system:

2017.08.28 22:20:53.474 Terminal        MetaTrader 5 x64 build 1653 started (MetaQuotes Software Corp.)
2017.08.28 22:20:53.476 Terminal        Windows 10 Pro (x64 based PC), IE 11.00, UAC, Intel Core i3-3120 M  @ 2.50 GHz, RAM: 4830 / 8077 Mb, HDD: 315702 / 475588 Mb, GMT+02:00
2017.08.28 22:20:53.476 Terminal        C:\Users\barab\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075

At the moment of the tests, the "test" folder has been created in [data folder]\MQL5\Files and the text file "source.txt" with the following contents has been created in it:

FileCopy
The function copies the original file from a local or shared folder to another file.
bool  FileCopy( 
   const string  src_file_name,     // Name of a source file 
   int           common_flag,       // Location 
   const string  dst_file_name,     // Name of the destination file 
   int           mode_flags         // Access mode 
   );


So, step 1: Copying "source.txt" file into another one using MQL5 tools

Script:

//--- display the window of input parameters when launching the script 
#property script_show_inputs 
//--- input parameters 
input string InpSrc="test\\source.txt";       // source 
input string InpDst="test\\destination.txt";  // copy 
input int    InpEncodingType=FILE_ANSI; // ANSI=32 or UNICODE=64 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnStart()
  {
//--- display the source contents (it must exist) 
   if(!FileDisplay(InpSrc))
      return;
//--- check if the copy file already exists (may not be created) 
   if(!FileDisplay(InpDst))
     {
      //--- the copy file does not exist, copying without FILE_REWRITE flag (correct copying) 
      if(FileCopy(InpSrc,0,InpDst,0))
         Print("File is copied!");
      else
         Print("File is not copied!");
     }
   else
     {
      //--- the copy file already exists, try to copy without FILE_REWRITE flag (incorrect copying) 
      if(FileCopy(InpSrc,0,InpDst,0))
         Print("File is copied!");
      else
         Print("File is not copied!");
      //--- InpDst file's contents remains the same 
      FileDisplay(InpDst);
      //--- copy once more with FILE_REWRITE flag (correct copying if the file exists) 
      if(FileCopy(InpSrc,0,InpDst,FILE_REWRITE))
         Print("File is copied!");
      else
         Print("File is not copied!");
     }
//--- receive InpSrc file copy 
   FileDisplay(InpDst);
  }
//+------------------------------------------------------------------+ 
//| Read the file contents                                           | 
//+------------------------------------------------------------------+ 
bool FileDisplay(const string file_name)
  {
//--- reset the error value 
   ResetLastError();
//--- open the file 
   int file_handle=FileOpen(file_name,FILE_READ|FILE_WRITE|FILE_TXT|InpEncodingType);
   if(file_handle!=INVALID_HANDLE)
     {
      //--- display the file contents in the loop 
      Print("+---------------------+");
      PrintFormat("File name = %s",file_name);
      while(!FileIsEnding(file_handle))
         Print(FileReadString(file_handle));
      Print("+---------------------+");
      //--- close the file 
      FileClose(file_handle);
      return(true);
     }
//--- failed to open the file 
   PrintFormat("%s is not opened, error = %d",file_name,GetLastError());
   return(false);
  }
//+------------------------------------------------------------------+


Step 2: Cleaning of "test" folder using MQL5 tools

Script:

//+------------------------------------------------------------------+
//|                                                  FolderClean.mq5 |
//|                              Copyright © 2017, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2017, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
//--- Description 
#property description "The script shows a sample use of FolderClean()." 
//--- Show the dialog of input parameters when starting the script 
#property script_show_inputs 
//--- Input parameters 
input string   foldername="test";  // folder in MQL5/Files/ 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnStart()
  {
//--- Start to delete files 
   PrintFormat("Trying to delete all files from folder %s",foldername);
   if(FolderClean(foldername,0))
      PrintFormat("Files have been successfully deleted, %d files left in folder %s",
                  foldername,
                  FilesInFolder(foldername+"\\*.*",0));
   else
      PrintFormat("Failed to delete files from folder %s. Error code %d",foldername,GetLastError());
//--- 
  }
//+------------------------------------------------------------------+ 
//| Returns the number of files in the specified folder              | 
//+------------------------------------------------------------------+ 
int FilesInFolder(string path,int flag)
  {
   int count=0;
   long handle;
   string filename;
//--- 
   handle=FileFindFirst(path,filename,flag);
//--- If at least one file found, search for more files 
   if(handle!=INVALID_HANDLE)
     {
      //--- Show the name of the file 
      PrintFormat("File %s found",filename);
      //--- Increase the counter of found files/folders 
      count++;
      //--- Start search in all files/folders  
      while(FileFindNext(handle,filename))
        {
         PrintFormat("File %s found",filename);
         count++;
        }
      //--- Do not forget to close the search handle upon completion 
      FileFindClose(handle);
     }
   else // Failed to get the handle 
     {
      PrintFormat("Files search in folder %s failed",path);
     }
//--- Return the result 
   return count;
  }
//+------------------------------------------------------------------+


Step 3: Deletion of the "test" folder using MQL5 tools

//+------------------------------------------------------------------+
//|                                                 FolderDelete.mq5 |
//|                              Copyright © 2017, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2017, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
//--- Description 
#property description "The script shows a sample use of FolderDelete()." 
#property description "First two folders are created; one of them is empty, the second one contains a file." 
#property description "When trying to delete a non-empty folder, an error is returned and a warning is shown."

//--- Show the dialog of input parameters when starting the script 
#property script_show_inputs 
//--- Input parameters 
input string   InpFolder="test";     // An empty folder 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnStart()
  {
//--- Delete the comment form the chart 
   Comment("");
//--- Add a message into the "Experts" journal 
   PrintFormat("Trying to delete folder %s",InpFolder);
   ResetLastError();
//--- Delete the empty folder 
   if(FolderDelete(InpFolder))
      //--- The following message should appear since the folder is empty 
      PrintFormat("Folder %s has been successfully deleted",InpFolder);
   else
      PrintFormat("Failed to delete folder %s. Error code=%d",InpFolder,GetLastError());
//--- 
  }
//+------------------------------------------------------------------+


What's the problem? Everything works.

Files:
 
Vladimir Karputov:

What's the big deal? Everything works.

Thanks for that example. I'll figure it out tomorrow morning. I don't have the energy right now.)

I'll test everything and give you an answer.


Added:

You've cited three different scripts here.

I have one program and copying, erasing files and folders happens within one function in two cycles.

Enter the first cycle: First the source files are copied to another folder, then those source files are erased. Exit the first cycle.

Enter the second loop: We clear the source folder with FolderClean() and erase the source folder with -FolderDelete().


Then we look in the file navigator in the meta-editor and see that the source folder has been partially erased. Subfolders that had no files were completely erased and those that had some files are not erased, but are empty.

Trying to remove folders manually - we've got it:



Then we close the terminal and start it again. We see that some subfolders disappeared on their own, others remained. We erase them manually without any problems. This time.