【MQL5】FileSize関数について

MQL5リファレンス
スポンサーリンク
スポンサーリンク
  1. FileSize関数の働き・役割
  2. FileSize関数の引数について
  3. FileSize関数の戻り値について
  4. FileSize関数を使ったサンプルコード
    1. 1. 入力パラメータの設定
    2. 2. フォルダ内のCSVファイルを検索
    3. 3. ファイルの開閉とサイズ取得
    4. 4. ファイルサイズに応じた移動
    5. 5. 全ファイルの処理
    6. 6. 処理の終了
  5. サンプルコード解説1:プロパティ命令及びグローバル領域部分
    1. プロパティ命令:#property script_show_inputs
    2. グローバル領域:入力パラメータ
      1. InpThresholdSize
      2. InpBigFolderName
      3. InpSmallFolderName
    3. グローバル領域について
  6. サンプルコード解説2:OnStart関数部分その1
    1. 変数の宣言
      1. file_name
      2. filter
      3. file_size
      4. size
    2. エキスパートログへの出力
    3. ファイル検索の開始
  7. サンプルコード解説3:OnStart関数部分その2
    1. FileFindFirst関数の結果確認
    2. ファイルの操作
      1. ファイルを開く
      2. エラーリセット
      3. 正常にファイルが開かれたか確認
      4. FileSize関数によるファイルサイズの取得
      5. ファイルを閉じる
  8. サンプルコード解説4:OnStart関数部分その3
    1. ファイルの開閉エラー処理
    2. ファイルサイズのログ出力
    3. ファイルの移動パスの定義
  9. サンプルコード解説5:OnStart関数部分その4
    1. ファイルの移動処理
      1. エラーハンドリング
    2. 次のファイルの処理
  10. サンプルコード解説6:OnStart関数部分その5
    1. FileFindClose関数によるハンドルの閉鎖
    2. エラーメッセージの出力

FileSize関数の働き・役割

FileSize関数は、指定されたファイルのサイズをバイト単位で取得するために使用されます。ファイルのサイズを確認することで、そのファイルがどれだけのデータを保持しているかを把握することができます。特に、ファイルの処理や分類、転送などを行う際に、そのサイズを基に条件を分岐させる場合に役立ちます。

ファイルを開くためには、まずFileOpen関数を使用してファイルハンドルを取得し、そのハンドルFileSize関数に渡す必要があります。FileSize関数は、ファイルハンドルを受け取り、そのファイルのサイズを返します。

FileSize関数の引数について

ulong  FileSize(
  int  file_handle    // ファイルハンドル
  );

FileSize関数は、1つの引数を取ります。

file_handle

file_handleは、FileOpen関数から取得されたファイルハンドルです。このファイルハンドルを指定することで、FileSize関数はそのファイルのサイズをバイト単位で取得します。

FileOpen関数は、ファイルを開いた際に一意(1つしか存在しない)の識別子としてファイルハンドルを返します。このハンドルを使用して、ファイルのサイズや内容にアクセスすることができます。

FileSize関数を使う際には、必ずFileOpen関数で有効なファイルハンドルを取得してから、この引数として渡す必要があります。

FileSize関数の戻り値について

FileSize関数は、指定されたファイルのサイズをバイト単位で返します。戻り値の型は ulong型です。

この戻り値により、ファイルのデータ量を正確に把握することができ、ファイルの分類やデータ処理に役立てることが可能です。

なお、FileSize関数が正常に動作しなかった場合やエラーが発生した場合、戻り値0 となります。この際、エラーの詳細情報は GetLastError関数を使用して確認することができます。

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

//--- スクリプトの起動時に入力パラメータのウィンドウを表示する指示
#property script_show_inputs

//--- 入力パラメータ
input ulong InpThresholdSize=20;       // ファイルサイズのしきい値(キロバイト単位で指定)
input string InpBigFolderName="big";   // 大きいファイルを保存するフォルダ名
input string InpSmallFolderName="small"; // 小さいファイルを保存するフォルダ名

//+------------------------------------------------------------------+
//| スクリプトの開始を指示する関数                                    |
//+------------------------------------------------------------------+
void OnStart()
{
  string file_name;      // 検索結果として見つかったファイルの名前を格納する変数
  string filter="*.csv"; // 検索するファイルの種類(ここではCSVファイルを対象とする)
  ulong file_size=0;     // ファイルサイズ(バイト単位)を格納する変数
  int size=0;            // 見つかったファイルの数を格納する変数

  //--- 現在操作しているファイルのフォルダパスをエキスパートログに出力
  PrintFormat("現在 %s\\Files\\ フォルダで作業中", TerminalInfoString(TERMINAL_COMMONDATA_PATH));

  //--- 全ての端末に共通のフォルダから最初のCSVファイルを見つけるための検索ハンドルを取得
  long search_handle = FileFindFirst(filter, file_name, FILE_COMMON);

  //--- FileFindFirst() が成功したかどうかを確認する
  if (search_handle != INVALID_HANDLE)
  {
    //--- 見つかったファイルを順に処理するループ
    do
    {
      //--- ファイルを開く
      ResetLastError(); // 前回のエラーをリセット
      int file_handle = FileOpen(file_name, FILE_READ | FILE_CSV | FILE_COMMON);

      //--- ファイルが正常に開かれたか確認
      if (file_handle != INVALID_HANDLE)
      {
        //--- FileSize関数を使って、開いたファイルのサイズを取得
        file_size = FileSize(file_handle);

        //--- ファイルを閉じる
        FileClose(file_handle);
      }
      else
      {
        //--- ファイルが開けなかった場合はエラーメッセージを出力し、次のファイルに進む
        PrintFormat("%s ファイルを開けませんでした。エラーコード = %d", file_name, GetLastError());
        continue; // 次のループへスキップ
      }

      //--- ファイルのサイズをエキスパートログに出力
      PrintFormat("%s ファイルのサイズは %d バイトです", file_name, file_size);

      //--- ファイルを移動するパスを定義(しきい値を基準にフォルダを分ける)
      string path;
      if (file_size > InpThresholdSize * 1024) // しきい値を超える場合、大きいファイルとして扱う
        path = InpBigFolderName + "//" + file_name;
      else // しきい値以下の場合、小さいファイルとして扱う
        path = InpSmallFolderName + "//" + file_name;

      //--- ファイルを指定したフォルダに移動する
      ResetLastError(); // 前回のエラーをリセット
      if (FileMove(file_name, FILE_COMMON, path, FILE_REWRITE | FILE_COMMON))
      {
        //--- 移動が成功した場合、エキスパートログにメッセージを出力
        PrintFormat("%s ファイルを移動しました", file_name);
      }
      else
      {
        //--- 移動に失敗した場合、エラーメッセージを出力
        PrintFormat("ファイル移動に失敗しました。エラーコード = %d", GetLastError());
      }

    } while (FileFindNext(search_handle, file_name)); // 次のファイルが存在するか確認

    //--- ファイル検索のためのハンドルを閉じる
    FileFindClose(search_handle);
  }
  else
  {
    //--- 検索が失敗した場合、エキスパートログにメッセージを出力
    Print("ファイルが見つかりませんでした!");
  }
}

このサンプルコード全体は、指定されたフォルダ内のすべてのCSVファイルを検索し、そのファイルサイズに応じて大きいファイルと小さいファイルを別々のフォルダに移動するという処理を行います。以下がコード全体の具体的な挙動です。

1. 入力パラメータの設定

ユーザーは、以下の3つの入力パラメータを指定できます。

  • InpThresholdSize:ファイルのしきい値サイズ(キロバイト単位)。この値を基準にしてファイルが大きいか小さいかを判断します。
  • InpBigFolderName:大きいファイルを移動するフォルダの名前。
  • InpSmallFolderName:小さいファイルを移動するフォルダの名前。

2. フォルダ内のCSVファイルを検索

スクリプトが実行されると、まず共通フォルダ内でCSVファイルを検索します。FileFindFirst関数を使用して、最初のCSVファイルを見つけ、その後FileFindNext関数を使って残りのCSVファイルを順次検索します。

3. ファイルの開閉とサイズ取得

見つけたファイルをFileOpen関数で開きます。開いたファイルが正常であれば、FileSize関数を使ってそのファイルのサイズを取得します。ファイルサイズが取得できたら、FileClose関数でファイルを閉じます。

4. ファイルサイズに応じた移動

取得したファイルサイズがしきい値(InpThresholdSize)よりも大きい場合は、大きいファイルとみなし、指定されたフォルダ(InpBigFolderName)に移動します。しきい値以下の場合は、小さいファイルとして、別のフォルダ(InpSmallFolderName)に移動します。

ファイルの移動にはFileMove関数を使用し、移動の成功または失敗に応じてエキスパートログにメッセージが記録されます。

5. 全ファイルの処理

すべてのCSVファイルに対して、この開閉・サイズ取得・移動の処理が行われます。次のファイルが見つかるたびに、同様の処理が繰り返され、全てのファイルが処理されるまでループが続きます。

6. 処理の終了

ファイル検索が終了した後、検索ハンドルが閉じられます。もし検索に失敗し、CSVファイルが見つからなかった場合は、エキスパートログに「ファイルが見つかりませんでした!」というメッセージが出力されます。

結果的に、このスクリプトは以下の動作を行います。

  • 指定フォルダ内のCSVファイルを検索し、ファイルサイズに基づいて分類します。
  • サイズに応じて、ファイルを「大きいファイル用のフォルダ」または「小さいファイル用のフォルダ」に移動します。
  • 各処理の結果やエラーはエキスパートログに記録され、問題があった場合はその内容も確認できます。

サンプルコード解説1:プロパティ命令及びグローバル領域部分

//--- スクリプトの起動時に入力パラメータのウィンドウを表示する指示
#property script_show_inputs

//--- 入力パラメータ
input ulong InpThresholdSize=20;       // ファイルサイズのしきい値(キロバイト単位で指定)
input string InpBigFolderName="big";   // 大きいファイルを保存するフォルダ名
input string InpSmallFolderName="small"; // 小さいファイルを保存するフォルダ名

このセクションでは、スクリプトのプロパティ命令およびグローバル領域で定義されている入力パラメータについて解説します。

プロパティ命令:#property script_show_inputs

property script_show_inputs は、スクリプトが実行される際に、入力パラメータのウィンドウを表示するための命令です。この命令を指定することで、スクリプトが実行されたときにユーザーが設定した入力パラメータを確認・編集するウィンドウが自動的に表示されます。

これにより、ユーザーはスクリプトの実行前に設定を変更できるため、複数の条件に柔軟に対応できるようになります。

グローバル領域:入力パラメータ

次に、input キーワードを用いて宣言された入力パラメータについて説明します。入力パラメータは、スクリプト実行時にユーザーが自由に設定できる変数です。これにより、ユーザーは実行ごとに異なる設定を適用できます。

InpThresholdSize

型:ulong型(符号なし長整数)

説明:ファイルサイズのしきい値を指定します。このスクリプトでは、ファイルサイズがこの値を基準にして「大きいファイル」か「小さいファイル」かを分類します。単位はキロバイトで、初期値として20KBに設定されています。

InpBigFolderName

型:string型文字列

説明:大きいファイルを移動する先のフォルダ名を指定します。初期値は”big”に設定されています。

InpSmallFolderName

型:string型文字列

説明:小さいファイルを移動する先のフォルダ名を指定します。初期値は”small”に設定されています。

グローバル領域について

このコードでは、入力パラメータがグローバル領域に宣言されています。グローバル領域とは、プログラム全体で参照可能な変数定数が定義される場所です。これらのパラメータは、スクリプト内のどこからでもアクセスできるため、スクリプトの処理の中で広く使用されます。

サンプルコード解説2:OnStart関数部分その1

//+------------------------------------------------------------------+
//| スクリプトの開始を指示する関数                                    |
//+------------------------------------------------------------------+
void OnStart()
{
  string file_name;      // 検索結果として見つかったファイルの名前を格納する変数
  string filter="*.csv"; // 検索するファイルの種類(ここではCSVファイルを対象とする)
  ulong file_size=0;     // ファイルサイズ(バイト単位)を格納する変数
  int size=0;            // 見つかったファイルの数を格納する変数

  //--- 現在操作しているファイルのフォルダパスをエキスパートログに出力
  PrintFormat("現在 %s\\Files\\ フォルダで作業中", TerminalInfoString(TERMINAL_COMMONDATA_PATH));

  //--- 全ての端末に共通のフォルダから最初のCSVファイルを見つけるための検索ハンドルを取得
  long search_handle = FileFindFirst(filter, file_name, FILE_COMMON);

このセクションでは、OnStart関数の前半部分について解説します。OnStart関数は、スクリプトが実行された際に最初に呼び出される関数で、ここでファイルの検索や初期設定が行われます。

変数の宣言

OnStart関数の最初でいくつかの変数が宣言されています。

file_name

型:string型文字列

説明:検索結果として見つかったファイル名を格納するための変数です。この変数には、FileFindFirst関数FileFindNext関数で見つけたファイルの名前が代入されます。

filter

型:string型文字列

説明:検索対象のファイル形式を指定するフィルタです。この例では、*.csvというフィルタが指定されており、CSV形式のファイルを対象にしています。フィルタによって特定の拡張子を持つファイルのみが検索対象となります。

file_size

型:ulong型(符号なし長整数)

説明:ファイルのサイズをバイト単位で格納する変数です。この変数に、FileSize関数を使って取得したファイルサイズを代入します。

size

型:int型(整数)

説明:見つかったファイルの数を格納するための変数です。このコードではまだ使用されていませんが、ファイル数のカウントやその他の処理に活用することが可能です。

エキスパートログへの出力

PrintFormat関数を使用して、現在操作しているフォルダのパスをエキスパートログに出力しています。TerminalInfoString関数を使用して、ファイルの共通フォルダパスを取得し、その情報をログに記録することで、スクリプトが正しい場所で実行されているかを確認することができます。

ファイル検索の開始

FileFindFirst関数を使用して、指定されたフィルタ(この場合は*.csv)に基づいて、最初のファイルを検索しています。検索が成功すると、ファイル名がfile_nameに格納され、検索ハンドルがsearch_handleに返されます。この検索ハンドルは、後続の処理で検索を続行する際に使用します。

サンプルコード解説3:OnStart関数部分その2

  //--- FileFindFirst() が成功したかどうかを確認する
  if (search_handle != INVALID_HANDLE)
  {
    //--- 見つかったファイルを順に処理するループ
    do
    {
      //--- ファイルを開く
      ResetLastError(); // 前回のエラーをリセット
      int file_handle = FileOpen(file_name, FILE_READ | FILE_CSV | FILE_COMMON);

      //--- ファイルが正常に開かれたか確認
      if (file_handle != INVALID_HANDLE)
      {
        //--- FileSize関数を使って、開いたファイルのサイズを取得
        file_size = FileSize(file_handle);

        //--- ファイルを閉じる
        FileClose(file_handle);
      }

このセクションでは、OnStart関数内のファイル操作部分について解説します。ここでは、ファイルの開閉やサイズの取得といった基本的なファイル操作が行われます。

FileFindFirst関数の結果確認

まず、FileFindFirst関数によってファイルが正常に見つかったかを確認します。search_handleINVALID_HANDLEでない場合、ファイル検索が成功したことを意味し、次に進みます。この後、do-whileループが開始され、見つかったすべてのファイルに対して処理を実行します。

ファイルの操作

ファイルを開く

ループ内で、まずFileOpen関数を使用してファイルを開きます。ファイルを開く際には、FILE_READ(読み取り専用)、FILE_CSV(CSV形式ファイル)、およびFILE_COMMON(全端末に共通のフォルダ内のファイル)というフラグが指定されています。

  • FILE_READ: ファイルを読み取るために開きます。
  • FILE_CSV: ファイルのフォーマットをCSVファイルと指定します。
  • FILE_COMMON: 全端末で共通のフォルダ内にあるファイルを対象とします。

エラーリセット

ファイルを開く前に、ResetLastError関数を使用して、以前のエラーコードをリセットします。これにより、最新のエラー状態が取得できるようになります。

正常にファイルが開かれたか確認

ファイルが正常に開かれたかどうかは、file_handleINVALID_HANDLEでないかを確認することで判断されます。INVALID_HANDLEが返された場合、ファイルのオープンに失敗しているため、その場合のエラーメッセージは後の処理で記録されます。

FileSize関数によるファイルサイズの取得

ファイルが正常に開かれた場合は、次にFileSize関数を使用して、開かれたファイルのサイズをバイト単位で取得します。取得したサイズは、file_size変数に格納されます。

ファイルを閉じる

ファイルのサイズを取得した後、必ずFileClose関数を使用してファイルを閉じます。ファイルを適切に閉じることで、システムリソースが解放され、他の操作に支障が出ることを防ぎます。

サンプルコード解説4:OnStart関数部分その3

   else
      {
        //--- ファイルが開けなかった場合はエラーメッセージを出力し、次のファイルに進む
        PrintFormat("%s ファイルを開けませんでした。エラーコード = %d", file_name, GetLastError());
        continue; // 次のループへスキップ
      }

      //--- ファイルのサイズをエキスパートログに出力
      PrintFormat("%s ファイルのサイズは %d バイトです", file_name, file_size);

      //--- ファイルを移動するパスを定義(しきい値を基準にフォルダを分ける)
      string path;
      if (file_size > InpThresholdSize * 1024) // しきい値を超える場合、大きいファイルとして扱う
        path = InpBigFolderName + "//" + file_name;
      else // しきい値以下の場合、小さいファイルとして扱う
        path = InpSmallFolderName + "//" + file_name;

このセクションでは、OnStart関数内でファイルの開閉エラー処理や、ファイルのサイズに基づいた分類と移動に関する処理を解説します。

ファイルの開閉エラー処理

ファイルが開けなかった場合、file_handleINVALID_HANDLEであることを確認します。この場合、elseブロックに入り、PrintFormat関数を使用して、エラーメッセージをエキスパートログに出力します。エラーメッセージには、開けなかったファイルの名前と、GetLastError関数で取得したエラーコードが含まれます。

その後、continue文を使用して、現在のループをスキップし、次のファイルの処理に進みます。これにより、エラーが発生してもスクリプトの実行が中断されず、次のファイルの処理が継続されます。

ファイルサイズのログ出力

ファイルが正常に開かれ、FileSize関数によってファイルサイズが取得された場合、次にそのサイズをエキスパートログに出力します。PrintFormat関数を使い、ファイルの名前とサイズをバイト単位で表示します。

ファイルの移動パスの定義

取得したファイルサイズを基に、ファイルを分類する処理が行われます。ここでは、InpThresholdSize(キロバイト単位で指定されるしきい値)を基準にして、ファイルサイズがそのしきい値を超えているかどうかで、ファイルの移動先フォルダを決定します。

  • ファイルサイズがInpThresholdSizeを超える場合、大きいファイルとして扱い、InpBigFolderNameフォルダに移動します。
  • ファイルサイズがしきい値以下の場合、小さいファイルとして扱い、InpSmallFolderNameフォルダに移動します。

移動先のフォルダパスは、ファイル名とフォルダ名を結合して作成されます。

サンプルコード解説5:OnStart関数部分その4

      //--- ファイルを指定したフォルダに移動する
      ResetLastError(); // 前回のエラーをリセット
      if (FileMove(file_name, FILE_COMMON, path, FILE_REWRITE | FILE_COMMON))
      {
        //--- 移動が成功した場合、エキスパートログにメッセージを出力
        PrintFormat("%s ファイルを移動しました", file_name);
      }
      else
      {
        //--- 移動に失敗した場合、エラーメッセージを出力
        PrintFormat("ファイル移動に失敗しました。エラーコード = %d", GetLastError());
      }

    } while (FileFindNext(search_handle, file_name)); // 次のファイルが存在するか確認

このセクションでは、OnStart関数内のファイル移動処理と、次のファイルへの処理の流れについて解説します。

ファイルの移動処理

ファイルサイズに応じた移動先フォルダが決定された後、FileMove関数を使用してファイルを新しい場所に移動します。FileMove関数は、次の引数を受け取ります。

  • file_name: 移動するファイルの名前。
  • FILE_COMMON: 移動元のファイルが共通フォルダにあることを示すフラグ
  • path: 移動先のフォルダパス。これは前の処理で、ファイルサイズに応じて決定されたパスです。
  • FILE_REWRITE | FILE_COMMON: 移動先に同名のファイルがあった場合、上書きするためのフラグ

エラーハンドリング

ファイルを移動する前に、ResetLastError関数を呼び出して前回のエラー状態をリセットします。これにより、新しいエラーが正しく検出できるようになります。

移動が成功した場合、PrintFormat関数を使用して、移動したファイルの名前をエキスパートログに出力します。逆に、移動に失敗した場合は、GetLastError関数を用いてエラーコードを取得し、そのエラーコードと共にエラーメッセージをエキスパートログに出力します。

次のファイルの処理

do-whileループの最後で、FileFindNext関数を使用して、次のファイルが存在するかを確認します。もし次のファイルが見つかれば、ループの先頭に戻って同じ処理(ファイルの開閉、サイズの取得、移動)を行います。次のファイルが存在しない場合は、ループが終了します。

サンプルコード解説6:OnStart関数部分その5

 //--- ファイル検索のためのハンドルを閉じる
    FileFindClose(search_handle);
  }
  else
  {
    //--- 検索が失敗した場合、エキスパートログにメッセージを出力
    Print("ファイルが見つかりませんでした!");
  }
}

このセクションでは、OnStart関数の最後の部分で行われているファイル検索の終了処理について解説します。

FileFindClose関数によるハンドルの閉鎖

すべてのファイルの処理が完了した後、FileFindClose関数を使用して、ファイル検索に使用したsearch_handleを閉じます。検索ハンドルは、ファイル検索を行うためにFileFindFirst関数FileFindNext関数で使用されており、このハンドルを閉じることでシステムリソースが解放されます。

ハンドルを閉じないままにしておくと、システムリソースの無駄遣いとなり、他のファイル操作に影響を与える可能性があるため、必ず最後に閉じる必要があります。

エラーメッセージの出力

もしファイル検索が失敗し、FileFindFirst関数INVALID_HANDLEを返した場合、検索が失敗したことを示しています。この場合は、elseブロックに入り、Print関数を使って「ファイルが見つかりませんでした!」というメッセージをエキスパートログに出力します。

これにより、ユーザーはファイルが存在しなかったことを確認でき、スクリプトの実行結果を把握できます。

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