閉じていないファイルがある場合、フォルダは削除されない - ページ 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を終了する前にファイルを閉じる必要があります。そして、ハンドルは、できればプログラムのどの場所からもアクセスできることが望ましい。これは私の意見です。さらに良いのは、そのファイルに対する読み書きの操作の後、あるいはそのファイルに対して何もする必要がなかったとしても、すぐにそのファイルを閉じてしまうことです。

サンプルのドキュメントでは、どのようにやってはいけないかが示されているようです。

また、ファイルに書き込んだ場合、書き込んだファイルは、 FileFlushを使用してファイルI/Oバッファに残っているすべてのデータをディスクに フラッシュするか、ファイルを 閉じることによってのみ読み出すことができることを覚えておくことは非常に重要である。ファイルを閉じると、ディスクのデータは強制的にリセットされます。

まとめ:ファイルを開いたら、閉じることを忘れずに。また、ファイルハンドルが失われることはありません。

もう一度言いますが、私のプログラムが作成したファイルは、FileClose()関数を使って閉じることができます - 私はそのハンドルを持っています。

他の人が作成した、Filesフォルダーに存在するファイルを閉じることができません。

自分が作ったのではない(自分のプログラムではない) ファイルをコピーした場合、コピー後にFileClose()関数で閉じることができません(ハンドルがない)、しかし、消去することはできます。

そのためか、コピーされたファイルや削除されたファイルがあるフォルダは、FolderClean()関数で削除されません。おそらく、コピーした後に閉じていなかったからでしょう。

しかし、取っ手がないので閉められません。

:)))

 

開発者に向けての質問です。

1. スクリプトを読み込む前に、Files フォルダに作成されたファイルのハンドルを取得するにはどうすればよいですか。

2.FolderClean() を使って、以前別のフォルダにコピーされ、コピー後に閉じられなかった(ハンドルがないため)フォルダ内のファイルを消した後に削除する問題は、上記のような原因が考えられますか?

 
Реter Konow:

開発者に向けての質問です。

1. スクリプトを読み込む前に、Files フォルダに作成されたファイルのハンドルを取得するにはどうすればよいですか。

2.FolderClean()関数で フォルダを削除する際、以前別のフォルダにコピーされ、コピー後に閉じられなかった(ハンドルがないため)フォルダ内のファイルを消去した後に削除する問題は、上記の理由が考えられますでしょうか。


これはOSの基本中の基本のようなものです。アプリケーションが書き込み用にファイルを開いている場合、そのファイルおよびそのファイルを含むフォルダーを削除することはできません。Wordでファイルを開き、OSのツールでそのファイルがあるフォルダーを削除してみてください。どうなるんだろう?できないでしょう、アクセスできないんだから。

しかし、ファイルハンドルを取得することができます。しかし、そのような行為に何の意味があるのでしょうか?結局、そのファイルを他のアプリケーションで開くと、前の文が表示されることになります。私たちのアプリケーションで有効なハンドルだけを取得します。

 
Ihor Herasko:

これはOSの基本中の基本のようなものです。アプリケーションが書き込み用にファイルを開いている場合、そのファイルおよびそのファイルを含むフォルダーは削除できません。Wordでファイルを開き、OSでそのファイルがあるフォルダーを削除してみてください。どうなるんだろう?できないでしょう、アクセスできないんだから。

まあ、ファイルハンドルを取得すればいいんですけどね。しかし、そのような行為に何の意味があるのでしょうか?結局、そのファイルを他のアプリケーションで開くと、前の文が表示されることになります。そ して、私たちの特定のアプリケーションで有効なハンドルだけを取得することができます。

そのファイルを私のアプリケーション(ファイルナビゲータ)で開き、別のフォルダに上書きします。

上書きした後、ファイルを閉じる 必要があるのですが、それができない(ハンドルがない)ので、ファイルを消去しています。

いつ、誰が作ったかわからないファイルなので、ハンドルがないのです。

同時に、Filesフォルダー内にファイルが存在し、他のフォルダーにコピーして消去することも可能です。

しかし、コピーした後、ファイルを閉じることができない。ハンドルがない。

このためか、消去したファイルを含むフォルダのFolderClean()をさらに実行しても、うまくいきません。


質問:このファイルのハンドルをMQLプログラムに取り込むにはどうしたらいいのでしょうか?

 

これは、まだコミュニティで直面していない問題のようです...。:)

よし、何か考えよう。

いつもそうなんです(笑)

 

神話を否定する。

そこで、OS上の端末データ。

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]の中に "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ツールによる "test "フォルダのクリーニング

スクリプト

//+------------------------------------------------------------------+
//|                                                  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ツールによる「test」フォルダの削除

//+------------------------------------------------------------------+
//|                                                 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:

何が大変なんだ?すべてがうまくいく。

その例には感謝します。明日の朝、考えてみるよ。今はその気力がない)

全部テストして答えを出します。


追加されました。

あなたはここで3つの異なるスクリプトを引用しています。

私は1つのプログラムを持っていて、ファイルやフォルダのコピー、消去が1つの機能内で2サイクルで行われます。

最初のサイクルに入る:まずソースファイルを 別のフォルダーにコピー し、次にそのソースファイルを消去する。第1サイクルを終了する。

FolderClean()でソース・フォルダをクリアし、-FolderDelete()でソース・フォルダを消去しています。


そして、メタエディタのファイルナビゲータを見ると、ソースフォルダが一部消されていることがわかります。ファイルがないサブフォルダは完全に消去され、何らかのファイルがあったサブフォルダは消去されずに空になっています。

手動でフォルダを削除しようとする - 私たちはそれを持っています。



そして、端末を一度終了し、再度起動する。あるサブフォルダーは勝手に消え、あるサブフォルダーは残っていることがわかります。問題なく手動で消去しています。今回は