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

 

TheXpert:

OMG!アウトプットするところは、ナンセンスです。だから、「OOPの方が速い」とか「インジケータは遅いから、Expert Advisorに全コードを入れるべき」といった主張が生まれるのです。

すべてが予定通りにいかないのは理解できますが、少なくとも、FileFlush() を普通に使う方がFileClose()よりも速いはず です。

しかし、やはりそういうものはループに入れるべきでない、どうせ大した役には立たない、と思っています。

また、MQL4の例を正しく理解すると、 FileFlush()の 呼び出しは 2つのループの間に置かれています(ループ内のブレーキになることが示唆されました)

  int bars_count=Bars;
  int handle=FileOpen("mydat.csv",FILE_CSV|FILE_WRITE);
  if(handle>0)
    {
     FileWrite(handle, "#","OPEN","CLOSE","HIGH","LOW");
     for(int i=0;i<bars_count;i++)
       FileWrite(handle, i+1,Open[i],Close[i],High[i], Low[i]);
     

FileFlush(handle);

     ...      for(int i=0;i<bars_count;i++)        FileWrite(handle, i+1,Open[i],Close[i],High[i], Low[i]);      FileClose(handle);     }

したがって、私が開発者の論理を正しく理解するならば、ファイルは メインクラスの OnInit / コンストラクタで開か れ(コンストラクタだけでないかもしれませんが)、メインクラスの OnDeint / Destructive で閉じられるはず です。

その他の場合は FileCloseの 代わりに FileFlushを使用します(FileWriteの後、ループの後


 

TheXpert:

イェデルキン

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

         FileFlush(handle_file);
         FileWrite(handle_file,t);

これは、ドキュメントのどこに書かれているのですか?

MQL5リファレンスに そのような文言があります。

FileFlush

備考

FileFlush()関数は、ファイルからの読み込みとファイルへの書き込みの操作の間に呼び出される必要があります。

ファイルへの書き込み」==FileWrite() 関数の場合、読み込み"FileFlush()関数は FileWrite() 関数の前に 呼び出す必要があります"。それとも、違う意見があるのでしょうか?

TheXpert です。

イェデルキン
しかし、 FileWrite()の 前にFileFlush()を呼び出す意味が まだ わかりません。

ないものにどうやって意味を持た せるのか?行の順番をトップページに戻して、再確認してください。どうやらドキュメントではうまく表現できていなかったようです。

新しい教材を勉強するときに、何が理にかなっていて、何が理にかなっていないのかが事前にわかると良いですね。自然は私たちにそのような才能を授けてはくれないので、私たちは「新しい高さに挑戦」し、テストし、文書と結果を解釈しなければならないのです。テストそのものが正しく書かれているかどうかもわからない。最初は直感的に FileWrite()後にFileFlush() を置いたの ですが、Handbookを読み直して、その例を削除 しました。

TheXpert です。

面白いですね

OMG!どこに出力するかがナンセンスなだけです。こうして、「OOPの方が速い」「インジケータは遅いから、Expert Advisorに全コードを入れるべき」といった主張が生まれるのです。

あなたの出力はバカだ」という評価の後に、「何がバカなのか」という説明があるといいのですが :)そうでなければ、このような司法の厳しさの中で、どのような方向に探究心をもって動けばよいのかが不明です :)

 
TheXpert:

変更が現れる前にフラッシュしても、まだそこにないのだから意味がない :)

信じられないと思いますが、まさにこのために、 以前のドキュメントを 参考に「しかし、 FileWrite()前にFileFlush() を呼ぶ意味がわからない」と書いたのです。 しかし、私はドキュメントのすべての行を疑うほどの神経と知識を持っていません :)
... まあ、コースは明確です - 私たちは、何らかの問題が本当に検出された場合、開発者が何を言うかを待っているのです。
 
Yedelkin:

MQL5リファレンスに そのような文言があります。

ファイルへの書き込み」==FileWrite() 関数の場合、読み込みを 行います。"FileFlush()関数は FileWrite() 関数の前に 呼び出す必要があります"。それとも、違う意見があるのでしょうか?

ここでは、「ちょっと残念な」MQL4 用関数の説明と使用例を紹介します。

voidFileFlush() int handle)


ファイル I/O バッファに残っている データをすべてディスクにリセットする。

注:FileFlush()関数は、ファイルの読み取りと書き込みの間に呼び出す必要があります。
ファイルが閉じられると、データは自動的にディスクにフラッシュされるので、FileClose() を呼ぶ前にFileFlush()を呼ぶ必要はない。

ここでマークされている行は、ファイルに書き込む前にFileFlushの呼び出しをループ 内に配置する必要性の引数である。

しかし、このコメントを一字一句理解すると、次のようになる。

FileFlush()関数は、ファイルからの読み込み(読み込みはFileReadXXX)とファイルへの書き込み(書き込みはFileWriteとFileWriteXXXで接続)の 操作の間に 呼び出す必要があります。

ファイルを閉じるとき(読み取り - FileClose実行時)、データは自動的にディスクにダンプ されます(読み取り - FileFlushの自動実行時)。


開発者はMQL4版でもヘルプを正しく読むことをあまり気にしていなかったと思います。切り捨てた部分をMQL5に入れようという話も馬鹿馬鹿しいとさえ思います。

少なくとも、上のコメントの第2文は、私の意見では次のようになるはずです。

ファイルを閉じると データは自動的にディスクにリセット されるので、FileClose() を呼び出す前にFileFlush()を呼び出す必要はない。

これも少し面倒ですが、ある観点から見ると、FileCloseを使って ファイルを閉じる前にFileFlushを使うべきでない理由が説明されています。


テキストには1つのこと(読み込みと書き込みの間の使用)が書かれており、例には2つのループ書き込み操作の間の使用が書かれています(ちなみにループ内の作業はヘルプでは全く考慮されていません)。

従って、最低限、以下を追加する必要がある。

1. この入出力バッファとは何か、また、ファイルを開き、データブロックを読み、データブロックを書き、ファイルを閉じるまでの間にバッファの中で実際に何が起こっているかを説明すること。

これは、ファイル操作に関するセクション全体を指している可能性が高いです。

2.単一のファイルアクセス(例:タイマー値の書き込み)にFileFlushコールを正しく使用する方法を、普通に理解できる例(クラスベースでも可)を挙げてください。

3 配列を扱う際の通常の呼び出し例を提供してください。 私の理解する限り、MQL4リファレンスに記載されている例は、大きな配列を扱うことに言及していますが、その説明は間違っています(一言で言えば、数回で済むなら、なぜかなり大量の同一データを2回ファイルに書き込むのか?)

FileFlush - Документация на MQL4
  • docs.mql4.com
FileFlush - Документация на MQL4
 
Interesting:

ここで強調されている行は、ファイルに書き込む前にループ内でFileFlushを呼び 出す必要があることを示す引数です。

しかし、このコメントを一字一句理解すると、次のようになる。

FileFlush()関数はファイルからの読み込み(読み込みはFileReadXXX)とファイルへの書き込み(書き込みはFileWriteとFileWriteXXXで接続)の 操作の間に 呼び出す必要があります。

ファイルを閉じるとき(読み取り - FileClose実行時)には、データは自動的にディスクにフラッシュ されます(読み取り - FileFlush実行時)。

なるほど、そういうことだったんですね。ファイルからの読み込み」をFileOpen()関数と同一視していたようです(私のExpert AdvisorはOnInit()からのみ読み込み、ティックやカスタムイベントの処理中は書き込みのみです。とはいえ、FileWriteXXX()の前にFileFlush()、どちらのリファレンスでも原理は同じです。 そして、古典的な意味での(自分の立場の理由付けとしての)議論ではなく、単になぜこのフレーズにしたのかという問いに対する答えでした。

とにかく、ここで開発者から返信がなければ、今夜、議論と中間結果へのリンクを貼って、要望を投稿します。2回でも応募が必要です。1)「バグ-ではない」、2)ドキュメントの変更。せっかくここまで掘り下げたのだから、2回目の応募は自分でやってみたいですか?

 
Yedelkin:

なるほど、なるほどと思うことがあります。正直に言うと、私は無意識のうちに「ファイルから読み込む」という操作を FileOpen() 関数と同一視していました(私の Expert Advisor は OnInit() からのみ読み込み、ティックとユーザーイベントの 処理中は書き込みのみです。とはいえ、FileWriteXXX()の前にFileFlush()、どちらのリファレンスでも原理は同じです。 そして、古典的な意味での(自分の立場を理由づけるような)論証ではなく、単になぜこのフレーズにしたのかという問いに対する答えに過ぎなかったのです。

とにかく、ここで開発者から返信がなければ、今夜、議論と中間結果へのリンクを貼って、要望を投稿します。2回でも応募が必要です。1)「バグ-ではない」、2)ドキュメントの変更。せっかく深く掘り下げたのだから、2回目のリクエストは自分でやってみるか?

1.そんなに奥が深いのでしょうか。 開発者がどこで何を言いたいのかがわかれば、喜んでやるかもしれませんね。

I/Oバッファについて言及されていても、適切な記述がないことがあります。それとも、ここにいる皆さんはFILE I/Oバッファが何であるか知っているのでしょうか?

この問題について、ファイル操作の章に普通に記述を追加することは難しいでしょうか?あるいは、開発者が何を考えていたのか、世界中をググって答えを探したのでしょうか?

ヘルプの規模が限られているのはわかりますが、なぜMQLを学び始めたばかりの人をバカにしなければならないのでしょうか。

2.なぜ、この機能のヘルプにしか、このバッファの記載がなく、ファイル操作のセクションの他の場所には記載がないのでしょうか?

3.この入出力のバッファについて、おおよそこのような形であることがわかったとします。

入出力バッファの 概念は、ファイルシステムと結びついている。入出力データはこのバッファを通じて行われる。

バッファとは、メモリ上にファイルごとに確保される領域の ことです。

ファイルへの記録は、まずすべての情報がバッファに 集められ、バッファの容量が一杯になるまで蓄積されます。 その後、またはダンプの特別なコマンドを実行した後でのみ、その情報はバッファに蓄積されます。 (例:FileCloseやFileFlush)。 バッファからファイルへのデータ転送を行います。

ファイルから読み込む場合、まずバッファにデータを読み込み ますが、要求されただけのデータを読み込むのではなく、バッファに収まるだけのデータを読み込みます。

そして、開発者は、これがMQLを勉強する新参者にとって興味深い情報ばかりだと本当に思っているのでしょうか(この定義だけがこの言語にとって有効だと考えられるのであれば)。

例えば、このバッファのサイズはどうなっているのか、どのように定義されているのかが気になりました。

私の意見では、これだけでなく、これらの情報はすべて言語のドキュメントに記載されるべきです(フォーラムでのさまざまな記事や議論ではなく、そこに)。

 
Interesting:
よし、自分で参考文献を書いてみよう
 

なぜスクリプトは、ファイルの実際の「最終読み取り日」を返さないのですか?

int handle_file;
void OnStart()
  {
   handle_file=FileOpen("Ye_file2.bin",FILE_READ|FILE_WRITE|FILE_BIN);
   switch(handle_file)
     {
      case  INVALID_HANDLE: break;
      default:
         Print("Дата создания файла Ye_file2.bin: ",(datetime)FileGetInteger(handle_file,FILE_CREATE_DATE));
         for(int i=0;i<3;i++)
           {
            Sleep(3000);
            FileReadInteger(handle_file,CHAR_VALUE);
            Print("Дата последнего чтения Ye_file2.bin: ",(datetime)FileGetInteger(handle_file,FILE_ACCESS_DATE));
           }
         FileClose(handle_file);
     }
  }
 
Yedelkin:

なぜスクリプトは、ファイルの実際の「最終読み取り日」を返さないのですか?

ラストアクセス、リードではありません。ハンドルを開き直すと、幸せになれる。
 
TheXpert:
リードアクセスではなく、ラストアクセス。

OK、お気づきかもしれませんが、私の質問では、ドキュメントからそのままのフレーズを引用しています。

enum_file_property_integer

識別子

識別子の説明

FILE_EXISTS

存在確認

ファイル作成日

作成日

ファイルモディファイ日付

最終修正日

ファイル_アクセス_日付

最終読取日

質問1:ドキュメントに誤字があり、「最終読み取り日」ではなく「最終開封日」のような表記になっていると思いますか?少なくとも、あなたの回答から、「ファイルを読む」操作と「ファイルにアクセスする」操作では意味が違うことがわかりますね。

さらに添付のスクリプトを何度か再起動すると、ほぼ同じ動作が確認できます。

FK      0       FileInteger (EURGBP,M1) 21:33:56        Дата создания файла Ye_file2.bin: 2011.09.03 21:22:25
IP      0       FileInteger (EURGBP,M1) 21:33:59        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:33:57
RL      0       FileInteger (EURGBP,M1) 21:34:02        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:33:57
NH      0       FileInteger (EURGBP,M1) 21:34:06        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:33:57
MH      0       FileInteger (EURGBP,M1) 21:34:43        Дата создания файла Ye_file2.bin: 2011.09.03 21:22:25
EP      0       FileInteger (EURGBP,M1) 21:34:46        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:34:06
 HL      0       FileInteger (EURGBP,M1) 21:34:50        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:34:06
IH      0       FileInteger (EURGBP,M1) 21:34:53        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:34:06

つまり、スクリプトを初めて実行したとき、FileReadInteger() の3回目の呼び出しは213406秒 に行われますが、最後の読み取り/アクセスの日付は21時33分57 秒と異なっています。しかし、2回目のスクリプト実行(37秒後)では、FileReadInteger() 関数の最初の呼び出しが21 時3406秒、つまり前回の スクリプト実行時にFileReadInteger() 関数を最後に呼び出した時間になっていることがわかります。

さらに、21時3443 秒に2回目のスクリプトの起動が発生しているので、あなたの言う「ハンドルの開き直し」も同時に発生したことになります。しかし、そのような「ハンドル再開」の後、21:34:06、つまり、あなたが言っているのとは全く異なる時間が返されるのです。

質問2:これはどう解釈すべきなのか?

TheXpert:
取っ手を開き直すと、幸せになれますよ。

現状では、ハンドルを「開き直す」ことなく、ファイルのプロパティを取得できるようになると朗報が期待される。