【MQL5】FileCopy関数について

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

FileCopy関数の働き・役割

FileCopy関数は、指定されたソースファイルをローカルフォルダまたは共有フォルダから別のファイルに複製するために使用されます。この関数を利用することで、特定のファイルを別の場所にコピーして利用することが可能です。特に、共有フォルダを使用することで複数のクライアント端末間でファイルを共有する際に便利です。

FileCopy関数の引数について

bool  FileCopy(
  const string  src_file_name,    // ソースファイル名
  int           common_flag,      // 場所
  const string  dst_file_name,    // ターゲットファイル名
  int           mode_flags        // アクセスモード
);

FileCopy関数は4つの引数を取ります。

src_file_name

src_file_nameは、これから複製されるファイルの名前を指定するもので、現時点ではまだ存在しないファイル名を指定します。コピー操作が成功すると、この名前のファイルが新たに作成されます。この引数文字列で、ファイル名を含みます。

common_flag

common_flagは、ファイルの場所を決めるフラグです。値がFILE_COMMONの場合、ファイルは全てのクライアント端末の共有フォルダ\Terminal\Common\Filesに存在します。

その他の場合、ファイルはローカルフォルダに存在します。例えば、common_flagに0を指定すると、ローカルフォルダ内のファイルを指します。

dst_file_name

dst_file_nameは、複製先のターゲットファイルの名称を指定します。この引数文字列で、ファイル名を含みます。

mode_flags

mode_flagsは、ファイルのアクセスモードを決定するフラグです。FILE_REWRITEおよび/またはFILE_COMMONの2つのフラグのみを含むことができ、他のフラグは無視されます。

FILE_REWRITE: 複製先のファイルが既に存在する場合でも、そのファイルを上書きします。FILE_COMMON: ファイルを全てのクライアント端末の共有フォルダに配置します。

ファイルが既存しFILE_REWRITEフラグが指定されていない場合、ファイルは書き換えされず、関数はfalseを返します。

FileCopy関数の戻り値について

FileCopy関数は、成功した場合にtrueを返し、失敗した場合にはfalseを返します。例えば、指定されたファイルが存在しない場合や、必要な権限がない場合には、falseが返されます。

FileCopy関数を使う際の注意点

セキュリティ上の理由から、MQL5ではファイルの扱いは厳しく制御されています。MQL5を用いて操作されるファイルは、ファイルサンドボックスの外に存在することはできません。新しいファイルが既存する場合、コピーはmode_flagsパラメータにFILE_REWRITEフラグがあるかどうかに応じて行われます。

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

以下にFileCopy関数を使用したサンプルコードを示します。このコードは、指定されたソースファイルをターゲットファイルに複製し、その結果を表示します。

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

//--- 入力パラメータの定義
input string InpSrc = "source.txt";        // 複製するソースファイル名
input string InpDst = "destination.txt";   // 複製先のターゲットファイル名
input int InpEncodingType = FILE_ANSI;     // ファイルエンコーディングの種類(ANSI = 32 または UNICODE = 64)

//+------------------------------------------------------------------+
//| スクリプトプログラムを開始する関数                              |
//+------------------------------------------------------------------+
void OnStart()
{
  //--- ソースファイルの内容を表示する(ファイルが存在する必要があります)
  if (!FileDisplay(InpSrc))
    return; // ファイルが存在しない場合は終了する

  //--- ターゲットファイルが既に存在するかどうかを確認する
  if (!FileDisplay(InpDst))
  {
    //--- ターゲットファイルが存在しない場合、フラグなしで複製する
    if (FileCopy(InpSrc, 0, InpDst, 0))
      Print("ファイルがコピーされました!");
    else
      Print("ファイルのコピーに失敗しました!");
  }
  else
  {
    //--- ターゲットファイルが既に存在する場合、フラグなしでのコピーを試みる
    if (FileCopy(InpSrc, 0, InpDst, 0))
      Print("ファイルがコピーされました!");
    else
      Print("ファイルのコピーに失敗しました!");
    
    //--- ターゲットファイルの内容は変わらないので内容を表示する
    FileDisplay(InpDst);
    
    //--- FILE_REWRITEフラグを使用して再度コピーを試みる(上書きコピー)
    if (FileCopy(InpSrc, 0, InpDst, FILE_REWRITE))
      Print("ファイルが上書きコピーされました!");
    else
      Print("ファイルの上書きコピーに失敗しました!");
  }

  //--- ターゲットファイルの内容を表示する
  FileDisplay(InpDst);
}

//+------------------------------------------------------------------+
//| ファイルの内容を読む関数                                         |
//+------------------------------------------------------------------+
bool FileDisplay(const string file_name)
{
  //--- エラー値をリセットする
  ResetLastError();

  //--- ファイルを開く(読み取りモード)
  int file_handle = FileOpen(file_name, FILE_READ | FILE_TXT | InpEncodingType);
  
  //--- ファイルが正常に開けた場合
  if (file_handle != INVALID_HANDLE)
  {
    //--- ファイルの内容をループで表示する
    Print("+---------------------+");
    PrintFormat("ファイル名 = %s", file_name);
    
    while (!FileIsEnding(file_handle))
      Print(FileReadString(file_handle)); // ファイルの内容を1行ずつ読み取って表示する
    
    Print("+---------------------+");
    
    //--- ファイルを閉じる
    FileClose(file_handle);
    
    return true; // ファイルの表示に成功した
  }
  
  //--- ファイルを開くのに失敗した場合
  PrintFormat("%s が開けませんでした。エラーコード = %d", file_name, GetLastError());
  
  return false; // ファイルの表示に失敗した
}

このサンプルコードは、以下のステップで動作します:

  1. ソースファイルの内容を表示します。
  2. ターゲットファイルが既に存在するかどうかを確認します。
  3. ターゲットファイルが存在しない場合、フラグなしで複製を試みます。
  4. ターゲットファイルが既に存在する場合、フラグなしで複製を試み、その後にFILE_REWRITEフラグを使用して再度複製を試みます。
  5. 最終的にターゲットファイルの内容を表示します。

サンプルコードに使われた関数や文法要素の簡単な解説

スクリプトの設定

#property script_show_inputs

このディレクティブは、スクリプトの起動時に入力パラメータのウィンドウを表示するために使用されます。これにより、ユーザーがスクリプトを実行する前に必要なパラメータを設定できます。

入力パラメータの定義

input string InpSrc = "source.txt";        // 複製するソースファイル名
input string InpDst = "destination.txt";   // 複製先のターゲットファイル名
input int InpEncodingType = FILE_ANSI;     // ファイルエンコーディングの種類(ANSI = 32 または UNICODE = 64)

inputキーワードを使用して、ユーザーがスクリプトを実行する際に設定できる入力パラメータを定義します。ここでは、ソースファイル名、ターゲットファイル名、およびエンコーディングの種類(初期値ANSIコード)を指定しています。

スクリプトのメイン関数

void OnStart()
{
  ...
}

OnStart関数は、スクリプトが実行されたときに最初に呼び出されるメイン関数です。この中でファイルの複製と表示を行います。

ファイルの表示関数

bool FileDisplay(const string file_name)
{
  ...
}

この関数は、指定されたファイルを開き、その内容をエキスパートログに表示します。以下の主要なステップで構成されています。※FileDisplay関数はオリジナル関数で、詳細な定義は一番下でおこなっています。

エラー値のリセット

ResetLastError();

ResetLastError関数は、最後に発生したエラーコードをリセットします。これにより、新しい操作のエラーを正確に検出できます。

ファイルを開く

int file_handle = FileOpen(file_name, FILE_READ | FILE_TXT | InpEncodingType);

FileOpen関数は、指定されたファイルを開きます。ここでは、読み取りモード、テキストファイルモード、および指定されたエンコーディングでファイルを開きます。成功すると、ファイルハンドルを返します。

ファイルの内容を表示

if (file_handle != INVALID_HANDLE)
{
   //--- ファイルの内容をループで表示する
  Print("+---------------------+");
  PrintFormat("ファイル名 = %s", file_name);
}

ファイルハンドルが有効である場合、ファイルの内容をエキスパートログに表示します。無効な場合、ファイルの開封に失敗したことを示します。

Print関数は、指定されたテキストをエキスパートログに出力するために使用されます。ここでは、ファイルの内容を見やすくするために、「+———————+」というラインを出力しています。このラインは視覚的な区切りを提供し、ログの読みやすさを向上させるためのものです。

PrintFormat関数は、フォーマット指定子を使用して文字列をフォーマットし、その結果をエキスパートログに出力します。ここでは、ファイル名を表示するために使用されています。

フォーマット指定子「%s」は、文字列を表すために使用されます。以下の例では、file_nameの値が%sの位置に挿入されて出力されます。

PrintFormat("ファイル名 = %s", file_name);

この行は、”ファイル名 = “という文字列に続いて、実際のファイル名を表示します。フォーマット指定子を使うことで、動的な内容を含む文字列を簡単に構築し、出力することができます。

ファイルの読み取りと表示

while (!FileIsEnding(file_handle))
  Print(FileReadString(file_handle));

FileIsEnding関数は、ファイルの終端に達したかどうかを確認します。FileReadString関数は、ファイルから一行を読み取って文字列として返します。これをエキスパートログに表示します。

ファイルを閉じる

FileClose(file_handle);

FileClose関数は、開いているファイルを閉じます。これにより、ファイルハンドルが解放され、他の操作ができるようになります。

ファイルのコピー操作

if (!FileDisplay(InpDst))
{
  if (FileCopy(InpSrc, 0, InpDst, 0))
    Print("ファイルがコピーされました!");
  else
    Print("ファイルのコピーに失敗しました!");
}

FileCopy関数は、ソースファイルをターゲットファイルに複製します。ここでは、ファイルが存在しない場合、フラグなしで複製を試みます。成功した場合はメッセージを表示し、失敗した場合はエラーメッセージを表示します。

再コピー操作

if (FileCopy(InpSrc, 0, InpDst, FILE_REWRITE))
  Print("ファイルが上書きコピーされました!");
else
  Print("ファイルの上書きコピーに失敗しました!");

ターゲットファイルが既に存在する場合、FILE_REWRITEフラグを使用して再度複製を試みます。このフラグにより、既存のファイルを上書きします。

このように、サンプルコードはFileCopy関数を使ったファイルの複製操作を行い、その結果を表示する方法を示しています。

コメント

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