ファイルを操作する - ページ 3

 
Yedelkin:
"ファイルを閉じるとき、データは自動的にディスクにダンプされるので、FileClose() を呼ぶ前に FileFlush() を呼ぶ必要はない" - そうそう、sergeev の言っていることが分かってきたよ。つまり、FileClose()の代わりにFileFlush()を呼び出せば、最後のレコードをファイルに保存することを保証できることがわかりましたね。そして、これがスマートな解決策になるのでしょうか?

代わりにではなく、必然的に。

Flush - 残りのデータをリセットし、ファイルを閉じない。これがあなたの望みでしょう?

Close-残りのデータをディスクにリセットして終了します。

 
sergeev:

代わりにではなく、必然的に。

Flush - 残りのデータをリセットし、ファイルを閉じない。これがあなたの望みでしょう?

Close - 残りのデータをディスクにフラッシュし、終了します。

はい、まさにその通りです。スマートな解決方法のヒントをありがとうございました
削除済み  
Yedelkin:

なんか、FileFlush()を使った時間最小化があまりうまくいかない。

2011.05.29 21:58:20 FlushSave (EURGBP,M1) FileFlush.GetTickCount() = 133766
2011.05.29 22:00:33 FlushSave (EURGBP,M1) FileClose.GetTickCount() = 133734
実際、どちらの機能も同じ時間がかかります。

私の理解では、この行はオフセットなしでファイルの先頭に位置を移動します。これにより、既存の情報を上書きすることができます(つまり、日付は更新されますが、ファイルに蓄積されることはありません)。

FileSeek(handle_file,0,SEEK_SET);

SEEK_SETの 代わりにmove to end of fileを使用することで、データがファイルに溜まってしまうのです。

 
Yedelkin:

フラッシュするたびに新しいファイルハンドルを開くのです。何のために?ちなみに閉じないんですね。

FileFlush関数の 利点は、ハンドルを開き直す必要がないことです。

Документация по MQL5: Файловые операции / FileFlush
Документация по MQL5: Файловые операции / FileFlush
  • www.mql5.com
Файловые операции / FileFlush - Документация по MQL5
 
Interesting:

1.私の理解では、この行はオフセットなしでファイル内の位置を移動させます。これにより、既存の情報を上書きすることができます(つまり、日付は更新されますが、ファイルには蓄積されません)。

従って、SEEK_SETの ファイル末尾へのスキップの代わりに使用すると、データがファイルに蓄積されます。
すでに私のメッセージを削除する時間がありました。そこに、ファイルに書き込んだ後にFileFlush()を挿入した例です。
 
TheXpert:

フラッシュするたびに新しいファイルハンドルを開くのです。何のために?ちなみに閉じないんですね。

FileFlush関数の 利点は、ハンドルを開き直す必要がないことです。

こんな感じでやりました。

int handle_file;
datetime t;
uint u;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---пример с функцией FileFlush()
   u=GetTickCount();
   handle_file=FileOpen("Ye_file.txt",FILE_READ|FILE_WRITE|FILE_TXT);
//for(int i=0;i<100000;i++)
   for(int i=0;i<1000;i++)
     {
      if(handle_file!=INVALID_HANDLE)
        {
         t=TimeLocal();
         FileSeek(handle_file,0,SEEK_SET);
         FileFlush(handle_file);
         FileWrite(handle_file,t);
        }
     }
   FileClose(handle_file);
   Print("FileFlush. GetTickCount() = ",GetTickCount()-u);

//---пример без функции FileFlush()
   u=GetTickCount();
   for(int i=0;i<1000;i++)
     {
      handle_file=FileOpen("Ye_file.txt",FILE_READ|FILE_WRITE|FILE_TXT);
      if(handle_file!=INVALID_HANDLE)
        {
         t=TimeLocal();
         FileSeek(handle_file,0,SEEK_SET);
         FileWrite(handle_file,t);
         FileClose(handle_file);
        }
     }
   Print("FileClose. GetTickCount() = ",GetTickCount()-u);
  }

結果

2011.05.29 23:14:31 FlushSave (EURGBP,M1) FileFlush.GetTickCount() = 13563
2011.05.29 23:14:32 FlushSave (EURGBP,M1) FileClose.GetTickCount() = 531

資料によると、ラインを入れ替えた。

         FileFlush(handle_file);
         FileWrite(handle_file,t);
しかし、 FileWrite()の 前にFileFlush()を呼び出す意味がわかりません。
削除済み  
Yedelkin:

こんな感じでやりました。

結果

2011.05.29 23:14:31 FlushSave (EURGBP,M1) FileFlush.GetTickCount() = 13563
2011.05.29 23:14:32 FlushSave (EURGBP,M1) FileClose.GetTickCount() = 531

ドキュメントにしたがって、ラインを入れ替えた。

しかし、 FileWrite()の 前にFileFlush()を呼び出す意味は、 まだ理解 されていない。

以下はそのバリエーションです。

int handle_file;
datetime t;
uint u;

void OnStart()
{
//---пример с функцией FileFlush()
u=GetTickCount();

handle_file=FileOpen("Ye_file.txt",FILE_READ|FILE_WRITE|FILE_TXT);

  for(int i=0;i<1000;i++)
  {
    if(handle_file!=INVALID_HANDLE)
    {
    t=TimeLocal();
    FileSeek(handle_file,0,SEEK_END);
    FileFlush(handle_file);
    FileWrite(handle_file,t);
    }
  }

FileClose(handle_file);

Print("FileFlush. GetTickCount() = ",GetTickCount()-u);

}

その結果がFileFlushです。GetTickCount()= 26125

以下はそのバリエーションです。

int handle_file;
datetime t;
uint u;

void OnStart()
{
//---пример без функции FileFlush()
u=GetTickCount();

  for(int i=0;i<1000;i++)
  {
  handle_file=FileOpen("Ye_file2.txt",FILE_READ|FILE_WRITE|FILE_TXT);
      
    if(handle_file!=INVALID_HANDLE)
    {
    t=TimeLocal();
    FileSeek(handle_file,0,SEEK_END);
    FileWrite(handle_file,t);
    FileClose(handle_file);
    }

  }

Print("FileClose. GetTickCount() = ",GetTickCount()-u);

}
結果はFileCloseです。GetTickCount() = 3969
削除済み  

このオプションは、47と110の間の結果を得た

int handle_file;
datetime t;
uint u;

void OnStart()
{

u=GetTickCount();

handle_file=FileOpen("Ye_file.txt",FILE_READ|FILE_WRITE|FILE_TXT);

  for(int i=0;i<1000;i++)
  {
    if(handle_file!=INVALID_HANDLE)
    {
    t=TimeLocal();
    FileSeek(handle_file,0,SEEK_END);
    FileWrite(handle_file,t);
    }
  }

FileClose(handle_file);

Print("FileFlush. GetTickCount() = ",GetTickCount()-u);

}

1.結論 - ループ内でFileFlushを使用 すると、実行速度が約260倍遅くなる。

2.このバリアントで50,000レコードのループを行うと、次のような結果になります - FileFlush.GetTickCount() = 1891.

3.50000書き込みサイクルを実行する際に、ファイルを終了させずにターミナルを終了させることに失敗しました(ターミナルを閉じてプロセスを "kill "しました)。

4.100000ループでterminalをkillし、ファイルには65536以上のレコードが含まれていました(Excel 2003でこれだけの容量があります)。

 
Yedelkin:

ドキュメントに従って、ラインを入れ替えた。

ドキュメントのどこにそんなことが書いてあるんだ?

しかし、 FileWrite()の 前にFileFlush()を呼ぶ意味が 未だに理解できません。

ないものにどうやって意味を持たせるのか?文字列の順序を返し、再確認する。どうやらドキュメントに正しく表現されていなかったようです。

でも...あなたのテストのおかげで、バグが検出されたようです -FileFlushは、変更が行われていないときに、非常に多くの時間を消費するようです。

面白いですね

OMG!推論がモロバレなところですね。OOPの方が速い」「インジケータは遅いから、コード全体をExpert Advisorに移すべき」といった主張が登場するのは、このためです。

 
papaklass:

専門家、この機能の正しい使い方を書いてください。

仮にそうだ。

// open handle
for(int i=0;i<1000;i++)
  {
    if(handle_file!=INVALID_HANDLE)
    {
    t=TimeLocal();
    FileSeek(handle_file,0,SEEK_END);
    FileWrite(handle_file,t);
    FileFlush(handle_file);
    }
  }
// close handle

つまり、FileClose -- FileOpenバンドルとFileFlushを 比較するのが正しい。

理論的には、FileFlushはFileCloseの一部であるべきで、バンドルより遅くなることはあり得ません。

変化が現れる前に流すのは、まだそこにないから意味がない :)

しかし、乱暴な結論ではありますが、このテストは指標となるものですので、変更がない場合の機能の動作については、開発者からのコメントをお待ちください。