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

 
mql5:
MQLの文字列はユニコード(1文字2バイト)、kernel32.dllの関数はアンシ(1文字1バイト)です。バイト配列と 関数 StringToCharArray を使って、ansish の関数を呼び出します。
どうしてですか?
確か、WindowsはほとんどUnicodeで、昔からそうだったような...。

それとも、kernel32.dllは例外なのでしょうか?

------追記--------。

見てみると、本当にアンシ、不思議・・・。

 

素人に一言アドバイス。ファイルを扱う知識は、Wordの使い手レベルです。

Expert Advisorは、作業時間中、ファイルの冒頭で毎回、ファイル内のdatetime型の値を1つ上書きする必要があります。最後に書き込んだ値を読み込む - Expert Advisor を再起動したときのみ。.csvファイルを使って、簡単な構造を作りました - すべてがうまくいっているようです。次のような質問が登場した。

1) プロシージャを書く時間を最小限にするために、datetime 値を保存するためにどのようなファイルタイプを使用するのが良いですか?私の理解では、.csvファイルは文字列で動作し、文字列があるところでは、その処理のために追加的な時間消費があります。

2)FileClose()の 正しい使い方 新しい値を書き込んだ後に毎回ファイルを閉じるべきか、OnDeinit()関数で一度だけ閉じるべきか?何度もファイルを開いては閉じるという無駄なことをせずに、一度ファイルを開いてから新しい値を書き込むだけでいいのですが。しかし、それは安全なのでしょうか?

3) ある値をファイルに書き込んだ後、そのファイルを閉じなければ、突然の停電の際にも書き込んだ値が消えることはなく、プログラムをロードすれば後で読み出すことができるという理解で正しいでしょうか。

 

Yedelkin:

以下のような疑問が出てきました。

1) プロシージャを書く時間を最小限にするために、datetime 値を保存するためにどのようなファイルタイプを使用するのがよいですか。私の理解では、.csvファイルは文字列で動作し、文字列があるところでは、その処理のために追加的な時間消費があります。

2)FileClose()の 正しい使い方:新しい値を書き込んだ後に毎回ファイルを閉じるべきか、OnDeinit()関数で一度だけ閉じるべきか? 何度もファイルを開いては閉じるという無駄なことをせずに、一度ファイルを開いてから新しい値を書き込むだけでいいのですが。しかし、それは安全なのでしょうか?

3) ある値をファイルに書き込んだ後、そのファイルを閉じなければ、突然の停電の際にも書き込んだ値が消えることはなく、プログラムをロードすれば後で読み出すことができるという理解で正しいでしょうか。

1.ファイルの保存形式によって異なります。日付は、数値、テキスト、またはdatetimeの 特殊な型として保存することができます。

2つ目の疑問は、「なぜファイルに保存するのか」「誰がどのように見るのか」ということです。

TXTへの書き込みは最も簡単で信頼性の高いオプションでしょう(どのプログラムからも、あるいはほとんどどのプログラムからも読み取ることができます)、CSVはファイルへの書き込みを 行うより高度な方法です。メリットもありますが、デメリットも確実にあります。

2.私は、OnInitまたはメインクラスのコンストラクタで一度開き(実装に依存)、OnDeinitまたはデストラクタで 閉じるのが好きです。

しかし、ファイルを再び開く/再開する必要がある場合(そのような動作にはさまざまな理由があります)、定期的(1時間/1日/1週間に1回)にそれを行うことができます。

ファイルが大きい場合や、中の情報の復元が困難な場合は、定期的に上書きするか、新規に作成するのがよいでしょう。

3. 値は書き込まれたが、ファイルが正しく閉じられなかった場合(突然の停電やソフトウェアのハングアップ)、ほとんどの場合、データは失われます(部分的か完全かは別の問題です)。

Delphiで書かれたプログラムで、プレーンテキストへの書き込みを実験したのを覚えています。問題の場合、最後の記録が破られていたり、欠落していたりすることが多かった。

 

ファイルの最終更新時刻を返すmql関数があれば、非常に歓迎します。

datetime FileLastModificationTime(string FName);
 
MetaDriver:

ファイルの最終更新時刻を返すmql関数があれば、非常に歓迎します。

datetime FileLastModificationTime(string FName); 
総じて、詩人冥利に尽きる。
 
Interesting:

1. 日付は、数字、テキスト、または特殊なdatetime タイプとして保存することができます。

日付をdatetime型で 保存する関数が見つかりませんでした。アレイを通してなら。

なぜか、datetime 型の値はバイナリファイルに保存したほうがよさそうです(ファイル自体はリロード時に同じ Expert Advisor からしか読み込まないように設計されています)。実験してみようと思います。

面白いですね

値が書き込まれたにもかかわらず、ファイルが正しく閉じられなかった場合(突然の停電やソフトウェアのハングアップ)、ほとんどの場合、データは失われます(部分的か完全かは別の問題です)。

Delphiで書かれたプログラムで、プレーンテキストに書き込む実験をしたのを覚えています。そこで問題が発生した場合、最後の記録は破られたり、欠落したりすることがよくありました。

それは残念です。最後の値の保存を保証したい場合は、FileClose() 関数を常に使用しなければならないことが判明しました:(

Документация по MQL5: Основы языка / Типы данных / Целые типы / Тип datetime
Документация по MQL5: Основы языка / Типы данных / Целые типы / Тип datetime
  • www.mql5.com
Основы языка / Типы данных / Целые типы / Тип datetime - Документация по MQL5
 
Yedelkin:

それは残念なことです。最後に書き込んだ値を確実に保存したい場合は、FileClose()を常に使用しなければならないことが判明した :(

そのために考案されたのがFileFlush() である。
 

sergeev:

イェデルキン

それは残念なことです。最後に書いた値を確実に保存したい場合は、FileClose()を常に使用しなければならないことが判明した :(

そのために考案されたのがFileFlush()である。

そうかもしれませんね。しかし、それをどう使うか(いつ使うか)については何も書かれていない。プロの方には簡単な質問かもしれませんが、個人的にはドキュメントを読んでもFileFlush()に特別な意味は感じられませんでした...。

また、FileClose()とFileFlush() の違いもまだ不明です :/。

FileFlush

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

...FileFlush() は、ファイル読み込みとファイル書き込みの間に呼び出すこと。

つまり、ファイルへの書き込みは行われず、データはすでにどこかで「ディスクにフラッシュ」されているのですね。

 
Yedelkin:

可能性がある。でも、どう使うか(いつ使うか)は書いていない。プロの方には簡単な質問かもしれませんが、個人的にはドキュメントを読んでもFileFlush()に特別な意味を感じないのですが...。

また、FileClose()とFileFlush() の違いもまだ不明です :/。

つまり、ファイルへの書き込みは行われていないが、データはすでにどこかで「フラッシュ」されている、ということでしょうか。

以下、MQL4 リファレンスより、より詳細な説明と例をご紹介します。

voidFileFlush() int handle)


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

注:FileFlush()は、ファイルの読み込みと書き込みの間に呼び出す必要があります。
ファイルを閉じると、データは自動的にディスクにリセットされるので、FileClose() を呼び出す前にFileFlush()を呼び出す必要はない。
パラメータ
手掛ける - FileOpen()が返すファイルディスクリプタ。

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

私の理解が正しければ、FileFlushコールはFileCloseとは異なり、ファイルを閉じないので、そのファイルを使用して作業を継続することができるのです。そして、開き直ることと比較すると、大幅なスピードアップが得られるはずです。

より具体的なタスクの例が必要ですが。

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

以下は、MQL4の ヘルプにある、例題を含むより詳細な説明です。

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