如果一个文件夹包含未关闭的文件,则不删除该文件夹 - 页 6

 
我想知道这一切是怎么回事。当我有空时,我会研究一下......当然,我希望有一个更简洁的任务说明
 
Vladimir Karputov:

请继续--只要你在 "小说 "这一迷人的体裁中写作。希望到了第40页左右,你会转到技术文献。

这个错误是隐含的。目前很难给出更多的技术细节。
 
Реter Konow:

我的所有文件都被删除了,甚至没有明确关闭它们。删掉了,因为我没有创建它们,而且它们以前在Files文件夹内。

问题是,为了删除一个文件,我们需要它的手柄。但是,如果我们没有创建这个文件,而只是把它放到了Files文件夹中,我们就不能得到它的句柄,因此我们就不能用FileClose() 关闭它。

同时,我们仍然可以复制或擦除它。然而,在此之后,无论是通过编程还是手动,都不能删除该文件夹。只有在重启终端后才能手动操作。

我稍后将尝试更清楚地再现这个问题,并举出说明性的例子。

代码只要完整就可以了。如果文件是打开的,必须在电脑关机或关闭MT4/5之前关闭它。而且,最好是在程序的任何地方都能接触到手柄。这是IMHO。更好的做法是,在你对文件进行读/写操作后,或者即使你不需要对它做任何事情,也要立即关闭该文件。

示例文档似乎显示了如何不这样做。

同样非常重要的是要记住,当向文件写入时,只有通过使用 FileFlush将文件I/O缓冲区中剩余的所有数据冲到磁盘上 ,或者关闭文件,才能读取所写入的文件。关闭该文件将强制重置数据到磁盘。

摘要:如果你打开一个文件,不要忘记关闭它。而且,文件柄也不会丢失。

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

代码只需要是完整的。如果文件是打开的,在关闭电脑或关闭MT4/5之前,应该关闭它。而这个手柄,最好是可以从程序中的任何地方进入。这是IMHO。最好是在对它进行读写操作后立即关闭该文件,或者即使你不必对它做任何事情。

示例文档似乎显示了如何不这样做。

同样非常重要的是要记住,当向文件写入时,只有通过使用 FileFlush将文件I/O缓冲区中剩余的所有数据冲到磁盘上 ,或者关闭文件,才能读取所写入的文件。关闭该文件将强制重置数据到磁盘。

摘要:如果你打开一个文件,不要忘记关闭它。而且,文件柄也不会丢失。

再次,我可以用FileClose()函数关闭我的程序所创建的文件--我有它的句柄。

我不能关闭一个由其他人创建的、但存在于Files文件夹中的文件,因为我没有它的句柄。

如果我复制的文件不是由我创建的(不是我的程序), 那么在复制后我不能用FileClose()函数关闭它(没有句柄),但我可以擦除它。

也许 这就是为什么带有复制和删除的文件的文件夹没有被FolderClean()函数删除。可能是,因为它们在被复制后没有被关闭。

但它们不能被关闭,因为它们没有手柄!

:)))

 

给开发者的问题。

1.如何获得加载脚本前在Files文件夹中创建的文件的句柄?

2.使用FolderClean()删除文件夹的问题,在删除其中的文件后,这些文件以前被复制到另一个文件夹,复制后没有关闭(因为没有句柄),是否有上述原因?

 
Реter Konow:

给开发者的问题。

1.如何获得加载脚本前在Files文件夹中创建的文件的句柄?

2.使用FolderClean()函数 删除文件夹的问题,在删除其中的文件后,这些文件以前被复制到另一个文件夹,复制后没有关闭(因为没有句柄),是否有上述原因?


这算是操作系统的基础知识。如果一个应用程序已经打开了一个文件进行写入,那么这个文件和包含它的文件夹都不能被删除。试着在Word中打开一个文件,然后用操作系统的工具来删除它所在的文件夹。将会发生什么?你不会的,因为你没有机会接触到它。

好吧,你可以得到文件的手柄。但这样的行动有什么好处呢?毕竟,如果该文件被其他应用程序打开,你会看到前面的声明。我们将只得到一个在我们的应用程序中有效的句柄。

 
Ihor Herasko:

这算是操作系统的基础知识。如果一个应用程序已经打开了一个文件进行写入,那么该文件和包含该文件的文件夹都不能被删除。试着在Word中打开一个文件,然后用操作系统删除它所在的文件夹。将会发生什么?你不会的,因为你没有机会接触到它。

好吧,你可以得到文件手柄。但这样的行动有什么好处呢?毕竟,如果该文件被其他应用程序打开,你会看到前面的声明。而 我们只能得到一个在我们的特定应用中有效的句柄。

该文件被我的应用程序(文件导航器)打开,被覆盖到另一个文件夹。

覆盖后,我需要关闭文件,但我不能--(没有句柄),所以我只是删除了文件。

没有句柄,因为该文件的创建时间和创建者都不清楚。

同时,该文件存在于Files文件夹内,可以被复制到另一个文件夹,然后被删除。

但在复制后,该文件不能被关闭。没有手柄。

这可能是为什么进一步清除文件夹的FolderClean()与被清除的文件,不工作。


问题:我如何将这个文件的句柄放入MQL程序?

 

这似乎是一个在社会上尚未面临的问题...:)

好的,我会想办法的。

我总是这样)。

 

揭开神话的面纱。

因此,操作系统上的终端数据。

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

在测试的时候,在[data folder]\MQL5\Files中创建了 "test "文件夹,并在其中创建了具有以下内容的文本文件 "source.txt"。

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 
   );


因此,第1步:使用MQL5工具将 "source.txt "文件复制到另一个文件中。

脚本。

//--- 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);
  }
//+------------------------------------------------------------------+


第2步:使用MQL5工具清理 "测试 "文件夹

脚本。

//+------------------------------------------------------------------+
//|                                                  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;
  }
//+------------------------------------------------------------------+


第3步:使用MQL5工具删除 "测试 "文件夹

//+------------------------------------------------------------------+
//|                                                 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());
//--- 
  }
//+------------------------------------------------------------------+


有什么问题呢?一切正常。

附加的文件:
 
Vladimir Karputov:

这有什么大不了的?一切正常。

谢谢你的例子。我明天早上会想出办法。我现在没有精力)。

我将测试一切,并给你一个答案。


已添加。

你在这里引用了三个不同的剧本。

我有一个程序,复制、删除文件和文件夹都是在一个功能内发生的,分两个周期。

进入第一个循环:首先,源文件被复制到 另一个文件夹,然后这些源文件被删除。退出第一个周期。

进入第二个循环:我们用FolderClean()清除源文件夹,用-FolderDelete()擦除源文件夹。


然后我们在元编辑器中的文件导航器中查看,发现源文件夹已经被部分删除了。没有文件的子文件夹被完全删除,有一些文件的子文件夹没有被删除,但却是空的。

试图手动删除文件夹--我们已经知道了。



然后我们关闭终端并再次启动它。我们看到,一些子文件夹自行消失了,其他子文件夹仍然存在。我们手动擦除它们,没有任何问题。这一次。