【MQL5】FileGetInteger関数について

MQL5リファレンス
スポンサーリンク

FileGetInteger関数の働き・役割

FileGetInteger関数は、ファイルの整数プロパティ(属性や情報)を取得するために使用されます。この関数には2つのバージョンがあり、ファイルハンドルでプロパティを取得する方法と、ファイル名でプロパティを取得する方法があります。

ファイルハンドルとは?

ファイルハンドルとは、ファイル操作を行う際に使用される一種の識別子です。ファイルを開くときに取得され、このハンドルを使用することで、特定のファイルに対して読み書きや属性取得などの操作を行うことができます。ファイルハンドルは、ファイルが開かれている間のみ有効であり、操作が完了したら必ず閉じる必要があります。

FileGetInteger関数の引数について

FileGetInteger関数は複数の書式を持つオーバーロード関数であり、ファイルハンドルでプロパティを取得する方法と、ファイル名でプロパティを取得する方法があります。

1. ファイルハンドルでプロパティを取得する場合

long FileGetInteger(
  int file_handle,                    // ファイルハンドル
  ENUM_FILE_PROPERTY_INTEGER property_id  // プロパティ識別子
);

2. ファイル名でプロパティを取得する場合

long FileGetInteger(
  const string file_name,              // ファイル名
  ENUM_FILE_PROPERTY_INTEGER property_id,  // プロパティ ID
  bool common_folder=false            // ファイルがローカルフォルダでみられる(false)
                                        // または全てのクライアント端末でみられる(true)
);

FileGetInteger関数の戻り値について

FileGetInteger関数は、指定されたプロパティの値を返します。プロパティの取得に成功した場合、そのプロパティの整数値が返されます。取得に失敗した場合は-1を返します。

エラーが発生した場合、具体的なエラーコードはGetLastError関数を使用して取得できます。ファイル名でプロパティを取得する際にフォルダを指定された場合、この関数は正しい戻り値を返しつつも、エラー5018(ERR_MQL_FILE_IS_DIRECTORY)を発生させることがあります。

FileGetInteger関数を使う際の注意点

FileGetInteger関数を使用する際の注意点は以下の通りです:

  • FileGetInteger関数は、呼び出されるたびにエラーコードを設定します。関数が正常に完了した場合、エラーコードは0(NULL)にリセットされますが、エラーが発生した場合は具体的なエラーコードが設定されます。このエラーコードは、GetLastError関数を使って確認できます。
  • ファイル名でプロパティを取得する場合、フォルダを指定するとエラー5018(ERR_MQL_FILE_IS_DIRECTORY)が発生することがあります。このエラーは、指定されたファイルがディレクトリである場合に発生します。

FileGetInteger関数を使ったサンプルコード

以下に、FileGetInteger関数を使用したサンプルコードを示します。このコードは、指定されたファイルのプロパティを取得してエキスパートログに出力します。

//--- スクリプトの起動時に入力パラメータのウィンドウを表示する
#property script_show_inputs
//--- 入力パラメータ
input string InpFileName="data.csv"; // デフォルトのファイル名
input string InpDirectoryName="SomeFolder"; // デフォルトのディレクトリ名

//+------------------------------------------------------------------+
//| スクリプトプログラムを開始する関数                              |
//+------------------------------------------------------------------+
void OnStart()
 {
  // ファイルパスを生成
  string path = InpDirectoryName + "\\" + InpFileName; 
  long l = 0; // プロパティ値を格納する変数

  //--- ファイルを開く
  ResetLastError(); // エラーコードをリセット
  int handle = FileOpen(path, FILE_READ | FILE_CSV); // ファイルを読み取りモードで開く
  if(handle != INVALID_HANDLE) // ファイルが正常に開かれたかを確認
    {
    //--- ファイルの情報を全て出力する
    Print(InpFileName, " file info:");
    FileInfo(handle, FILE_EXISTS, l, "bool"); // ファイルが存在するかどうか
    FileInfo(handle, FILE_CREATE_DATE, l, "date"); // ファイルの作成日
    FileInfo(handle, FILE_MODIFY_DATE, l, "date"); // ファイルの最終更新日
    FileInfo(handle, FILE_ACCESS_DATE, l, "date"); // ファイルの最終アクセス日
    FileInfo(handle, FILE_SIZE, l, "other"); // ファイルのサイズ
    FileInfo(handle, FILE_POSITION, l, "other"); // ファイル内の現在の位置
    FileInfo(handle, FILE_END, l, "bool"); // ファイルの終わりかどうか
    FileInfo(handle, FILE_IS_COMMON, l, "bool"); // ファイルが共有フォルダにあるかどうか
    FileInfo(handle, FILE_IS_TEXT, l, "bool"); // ファイルがテキストファイルかどうか
    FileInfo(handle, FILE_IS_BINARY, l, "bool"); // ファイルがバイナリファイルかどうか
    FileInfo(handle, FILE_IS_CSV, l, "bool"); // ファイルがCSVファイルかどうか
    FileInfo(handle, FILE_IS_ANSI, l, "bool"); // ファイルがANSIエンコードかどうか
    FileInfo(handle, FILE_IS_READABLE, l, "bool"); // ファイルが読み取り可能かどうか
    FileInfo(handle, FILE_IS_WRITABLE, l, "bool"); // ファイルが書き込み可能かどうか
    
    //--- ファイルを閉じる
    FileClose(handle); // ファイルハンドルを閉じる
    }
  else
    // ファイルが開けなかった場合のエラーメッセージを出力
    PrintFormat("%s file is not opened, ErrorCode = %d", InpFileName, GetLastError());
 }

//+------------------------------------------------------------------+
//| ファイルプロパティ値を表示する関数                               |
//+------------------------------------------------------------------+
void FileInfo(const int handle, const ENUM_FILE_PROPERTY_INTEGER id,
            long l, const string type)
 {
  //--- プロパティ値を受け取る
  ResetLastError(); // エラーコードをリセット
  if((l = FileGetInteger(handle, id)) != -1) // プロパティ値の取得に成功したかどうか
    {
    //--- 値を受け取ったので、正しいフォーマットで表示する
    if(!StringCompare(type, "bool"))
        Print(EnumToString(id), " = ", l ? "true" : "false"); // 真偽値として出力
    if(!StringCompare(type, "date"))
        Print(EnumToString(id), " = ", (datetime)l); // 日付として出力
    if(!StringCompare(type, "other"))
        Print(EnumToString(id), " = ", l); // その他の形式として出力
    }
  else
    // エラーが発生した場合のエラーメッセージを出力
    Print("Error, Code = ", GetLastError());
 }

若干複雑なので、小分けにして解説していきたいと思います。

解説1:グローバル領域の定義部分

//--- スクリプトの起動時に入力パラメータのウィンドウを表示する
#property script_show_inputs
//--- 入力パラメータ
input string InpFileName="data.csv"; // デフォルトのファイル名
input string InpDirectoryName="SomeFolder"; // デフォルトのディレクトリ名

#property script_show_inputs

#property script_show_inputsは、スクリプトが起動する際に入力パラメータウィンドウを表示するためのディレクティブです。
ディレクティブとは、コンパイラ(プログラムを機械語に翻訳するソフトウェア)に対して特定の動作を指示するための命令です。
このディレクティブを使用することで、ユーザーがスクリプトを実行する前に入力パラメータを設定できるようになります。

input string InpFileName=”data.csv”;

input string InpFileName="data.csv";は、スクリプトが実行される際にユーザーが指定できる入力パラメータを定義しています。このパラメータはスクリプトの実行中に変更することはできませんが、実行前にユーザーが値を設定できます。

  • input
    このキーワードは、ユーザーがスクリプト実行時に設定できるパラメータを定義するために使用されます。
  • string
    パラメータのデータ型を示しています。この場合、文字列型のパラメータです。
  • InpFileName
    パラメータの名前です。スクリプト内でこの名前を使用して、ユーザーが指定した値にアクセスします。
  • “data.csv”
    パラメータの初期値です。この初期値は、デフォルトで使用されるファイル名を示しています。

input string InpDirectoryName=”SomeFolder”;

input string InpDirectoryName="SomeFolder";も同様に、ユーザーが指定できる入力パラメータを定義しています。

  • input
    ユーザーがスクリプト実行時に設定できるパラメータを定義します。
  • string
    パラメータのデータ型を示しています。こちらも文字列型です。
  • InpDirectoryName
    パラメータの名前です。スクリプト内でこの名前を使用して、ユーザーが指定した値にアクセスします。
  • “SomeFolder”
    パラメータの初期値です。この初期値は、デフォルトで使用されるディレクトリ名を示しています。

これらの設定により、スクリプト実行時にユーザーがファイル名やディレクトリ名を簡単に指定できるようになります。

解説2:OnStart関数の中1

void OnStart()
 {
  // ファイルパスを生成
  string path = InpDirectoryName + "\\" + InpFileName; 
  long l = 0; // プロパティ値を格納する変数

  //--- ファイルを開く
  ResetLastError(); // エラーコードをリセット
  int handle = FileOpen(path, FILE_READ | FILE_CSV); // ファイルを読み取りモードで開く

void OnStart()

void OnStart()は、スクリプトが開始される際に最初に実行される関数です。MQL5では、スクリプトエキスパートアドバイザーインジケータなどの各プログラムタイプごとに特定のエントリポイント関数が用意されています。スクリプトの場合、OnStart関数がそのエントリポイントとなります。この関数戻り値を持たず、引数も取りません。スクリプトが実行されると、この関数内のコードが一度だけ実行されます。

ファイルパスを生成

string path = InpDirectoryName + "\\" + InpFileName;
  • string path
    新しい文字列型の変数pathを宣言しています。この変数はファイルのパスを格納します。
  • InpDirectoryName + “\” + InpFileName
    ディレクトリ名InpDirectoryNameとファイル名InpFileNameを連結して、完全なファイルパスを生成します。
  • バックスラッシュが2つ続いている理由:
    バックスラッシュ(\)はエスケープシーケンス(特定の機能を持つ文字列)を示すために使用されます。例えば、\nは改行を示します。しかし、単純に文字としてバックスラッシュを使用したい場合、エスケープシーケンスとして解釈されないようにするためには、バックスラッシュを2つ続けて記述する必要があります。これにより、文字列内で単一のバックスラッシュが表示されます。

プロパティ値を格納する変数

long l = 0;
  • long l
    新しい長整数型変数lを宣言し、0で初期化します。この変数は、後でファイルのプロパティ値を格納するために使用されます。

ファイルを開く

ResetLastError(); // エラーコードをリセット
  • ResetLastError()
    最後に発生したエラーコードをリセットします。ResetLastError関数を呼び出すことで、以前のエラーコードがクリアされ、次に発生するエラーを正しく検出できるようになります。
int handle = FileOpen(path, FILE_READ | FILE_CSV); // ファイルを読み取りモードで開く

セパレータの | の文法的役割

  • FILE_READ | FILE_CSV
    セパレータの | はビット単位の論理和演算子を示します。これは複数のフラグを組み合わせるために使用されます。ここでは、FILE_READとFILE_CSVの両方のモードでファイルを開くために使用されています。ビット単位の論理和演算により、各フラグビットが設定され、複数のオプションを同時に指定することができます。

解説3:OnStart関数の中2

 if(handle != INVALID_HANDLE) // ファイルが正常に開かれたかを確認
    {
    //--- ファイルの情報を全て出力する
    Print(InpFileName, " file info:");
    FileInfo(handle, FILE_EXISTS, l, "bool"); // ファイルが存在するかどうか
    FileInfo(handle, FILE_CREATE_DATE, l, "date"); // ファイルの作成日
    FileInfo(handle, FILE_MODIFY_DATE, l, "date"); // ファイルの最終更新日
    FileInfo(handle, FILE_ACCESS_DATE, l, "date"); // ファイルの最終アクセス日
    FileInfo(handle, FILE_SIZE, l, "other"); // ファイルのサイズ
    FileInfo(handle, FILE_POSITION, l, "other"); // ファイル内の現在の位置
    FileInfo(handle, FILE_END, l, "bool"); // ファイルの終わりかどうか
    FileInfo(handle, FILE_IS_COMMON, l, "bool"); // ファイルが共有フォルダにあるかどうか
    FileInfo(handle, FILE_IS_TEXT, l, "bool"); // ファイルがテキストファイルかどうか
    FileInfo(handle, FILE_IS_BINARY, l, "bool"); // ファイルがバイナリファイルかどうか
    FileInfo(handle, FILE_IS_CSV, l, "bool"); // ファイルがCSVファイルかどうか
    FileInfo(handle, FILE_IS_ANSI, l, "bool"); // ファイルがANSIエンコードかどうか
    FileInfo(handle, FILE_IS_READABLE, l, "bool"); // ファイルが読み取り可能かどうか
    FileInfo(handle, FILE_IS_WRITABLE, l, "bool"); // ファイルが書き込み可能かどうか

    //--- ファイルを閉じる
    FileClose(handle); // ファイルハンドルを閉じる
    }

if(handle != INVALID_HANDLE)

Print(InpFileName, ” file info:”)

  • 開いたファイルの情報を出力する準備をします。この行は、ファイル名と「file info:」というテキストをエキスパートログに出力します。

FileInfo(handle, FILE_EXISTS, l, “bool”)

  • FileInfo関数を呼び出して、特定のファイルプロパティを取得します。この場合、ファイルが存在するかどうか(trueまたはfalse)を確認します。

※FileInfo関数はオリジナル関数です。定義に関してはOnStart関数の下で行っています。

FileInfo(handle, FILE_CREATE_DATE, l, "date"); // ファイルの作成日
FileInfo(handle, FILE_MODIFY_DATE, l, "date"); // ファイルの最終更新日
FileInfo(handle, FILE_ACCESS_DATE, l, "date"); // ファイルの最終アクセス日
  • これらの呼び出しは、それぞれファイルの作成日、最終更新日、最終アクセス日を取得し、エキスパートログに出力します。
FileInfo(handle, FILE_SIZE, l, "other"); // ファイルのサイズ
FileInfo(handle, FILE_POSITION, l, "other"); // ファイル内の現在の位置
  • ファイルのサイズと現在の読み取り位置を取得し、エキスパートログに出力します。
FileInfo(handle, FILE_END, l, "bool"); // ファイルの終わりかどうか
  • ファイルの終わりに到達したかどうかを確認します。
FileInfo(handle, FILE_IS_COMMON, l, "bool"); // ファイルが共有フォルダにあるかどうか
FileInfo(handle, FILE_IS_TEXT, l, "bool"); // ファイルがテキストファイルかどうか
FileInfo(handle, FILE_IS_BINARY, l, "bool"); // ファイルがバイナリファイルかどうか
FileInfo(handle, FILE_IS_CSV, l, "bool"); // ファイルがCSVファイルかどうか
FileInfo(handle, FILE_IS_ANSI, l, "bool"); // ファイルがANSIエンコードかどうか
FileInfo(handle, FILE_IS_READABLE, l, "bool"); // ファイルが読み取り可能かどうか
FileInfo(handle, FILE_IS_WRITABLE, l, "bool"); // ファイルが書き込み可能かどうか
  • ファイルが共有フォルダにあるか、テキストファイル(文字データを含むファイル)か、バイナリファイル(テキスト以外のデータを含むファイル)か、CSVファイル(カンマ区切りの値を含むファイル)か、ANSIエンコード(ANSI文字コードでエンコードされたファイル)か、読み取り可能か、書き込み可能かをそれぞれ確認し、エキスパートログに出力します。

FileClose(handle)

解説4:OnStart関数の中3

else
    // ファイルが開けなかった場合のエラーメッセージを出力
    PrintFormat("%s file is not opened, ErrorCode = %d", InpFileName, GetLastError());
 }

else

  • if文の条件が満たされなかった場合に実行されるブロックを示します。ここでは、FileOpen関数ファイルハンドルを正常に返さなかった場合、つまりファイルが開けなかった場合に実行されます。

PrintFormat(“%s file is not opened, ErrorCode = %d”, InpFileName, GetLastError());

  • PrintFormat関数は、指定された形式に従って文字列をフォーマットし、エキスパートログに出力します。
  • %s
    これはフォーマット指定子で、文字列を挿入する場所を示します。ここでは、InpFileName(ユーザーが指定したファイル名)が挿入されます。
  • file is not opened
    この固定文字列は、ファイルが開けなかったことを示すメッセージです。
  • %d
    これはフォーマット指定子で、整数を挿入する場所を示します。ここでは、GetLastError関数によって返されるエラーコードが挿入されます。
  • GetLastError()
    GetLastError関数は最後に発生したエラーコードを取得する関数です。これにより、ファイルが開けなかった原因を特定するための情報が得られます。

この部分のコードは、ファイルを開けなかった場合にエラーメッセージをエキスパートログに出力し、エラーの原因を確認できるようにします。

解説5:オリジナル関数であるFileInfo関数の定義1

void FileInfo(const int handle, const ENUM_FILE_PROPERTY_INTEGER id,
            long l, const string type)

void FileInfo

  • voidは、この関数が値を返さないことを示します。

const int handle

const ENUM_FILE_PROPERTY_INTEGER id

ENUM_FILE_PROPERTY_INTEGERについての詳細は↓の記事をご参照ください。

  • constは、この引数関数内で変更されないことを保証します。

long l

  • プロパティ値を格納するための変数です。関数内でプロパティの値を取得し、この変数に格納します。

const string type

  • 取得するプロパティの型を示す文字列型の引数です。プロパティの型に応じて、値をどのように表示するかを決定します。
  • constは、この引数関数内で変更されないことを保証します。

この関数は、指定されたファイルハンドルとプロパティ識別子を使用してファイルのプロパティを取得し、プロパティの型に応じて適切にフォーマットして表示します。

解説6:オリジナル関数であるFileInfo関数の定義2

 {
  //--- プロパティ値を受け取る
  ResetLastError(); // エラーコードをリセット
  if((l = FileGetInteger(handle, id)) != -1) // プロパティ値の取得に成功したかどうか
    {
    //--- 値を受け取ったので、正しいフォーマットで表示する
    if(!StringCompare(type, "bool"))
        Print(EnumToString(id), " = ", l ? "true" : "false"); // 真偽値として出力
    if(!StringCompare(type, "date"))
        Print(EnumToString(id), " = ", (datetime)l); // 日付として出力
    if(!StringCompare(type, "other"))
        Print(EnumToString(id), " = ", l); // その他の形式として出力
    }
  else
    // エラーが発生した場合のエラーメッセージを出力
    Print("Error, Code = ", GetLastError());
 }

プロパティ値を受け取る

ResetLastError(); // エラーコードをリセット
  • ResetLastError
    ResetLastError関数は最後に発生したエラーコードをリセットします。これにより、新しいエラーが発生した際に正確なエラーコードを取得できます。
if((l = FileGetInteger(handle, id)) != -1) // プロパティ値の取得に成功したかどうか

値を受け取ったので、正しいフォーマットで表示する

StringCompare関数EnumToString関数は、それぞれ次のような役割を持つ関数です:

if(!StringCompare(type, "bool"))
    Print(EnumToString(id), " = ", l ? "true" : "false"); // 真偽値として出力
  • StringCompare(type, “bool”)
    typeが”bool”と一致するかどうかを確認します。一致する場合、真偽値としてプロパティを表示します。
  • Print(EnumToString(id), ” = “, l ? “true” : “false”)
    EnumToString(id)を使用してプロパティ識別子文字列に変換し、lの値に基づいて”true”または”false”を表示します。
  • 三項演算子
    三項演算子は、条件式 ? 真の場合の値 : 偽の場合の値

    という形式で使用されます。この場合、lが真(0以外の値)であれば”true”、偽(0の値)であれば”false”を返します。
if(!StringCompare(type, "date"))
    Print(EnumToString(id), " = ", (datetime)l); // 日付として出力
if(!StringCompare(type, "other"))
    Print(EnumToString(id), " = ", l); // その他の形式として出力
  • StringCompare(type, “other”)
    typeが”other”と一致するかどうかを確認します。一致する場合、その他の形式としてプロパティを表示します。
  • Print(EnumToString(id), ” = “, l)
    EnumToString(id)を使用してプロパティ識別子文字列に変換し、lの値をそのまま表示します。

エラーが発生した場合のエラーメッセージを出力

else
    Print("Error, Code = ", GetLastError());
  • else
    if文の条件が満たされなかった場合、つまりプロパティ値の取得に失敗した場合に実行されます。
  • Print(“Error, Code = “, GetLastError())
    エラーコードをエキスパートログに出力します。GetLastError関数を使用して、最後に発生したエラーコードを取得します。

この部分のコードは、FileGetInteger関数を使用してファイルプロパティを取得し、その値を適切な形式で表示します。プロパティの取得に失敗した場合は、エラーメッセージをログに出力します。

コメント

タイトルとURLをコピーしました