FileIsExist関数の働き・役割
FileIsExist関数は、指定されたファイルが存在するかどうかを確認するために使用されます。ファイルの存在をチェックすることで、ファイル操作の前提条件を確認することができます。
FileIsExist関数の引数について
FileIsExist関数の引数構成は以下の通りです。
bool FileIsExist(
const string file_name, // ファイル名
int common_flag=0 // 検索の場所
);
引数の説明
file_name: 種類: 文字列型
説明: チェックされるファイルの名称を指定します。パス(ファイルの位置を示す文字列)を含むファイル名を指定することもできます。
common_flag=0: 種類: 整数型
説明: ファイルの場所を決めるフラグです。FILE_COMMONを指定すると、ファイルは全てのクライアント端末の共有フォルダ(複数のユーザーがアクセスできるフォルダ)\Terminal\Common\Files 内に存在します。その他の場合、ファイルはローカルフォルダ(特定のユーザーのみがアクセスできるフォルダ)に存在します。
FileIsExist関数の戻り値について
FileIsExist関数は、指定されたファイルが存在する場合にtrueを返し、存在しない場合にfalseを返します。
FileIsExist関数を使う際の注意点
FileIsExist関数を使用する際には、以下の点に注意する必要があります。
- file_nameには正確なファイルパス(ファイルの位置を示す文字列)を指定することが重要です。相対パス(現在のフォルダを基準にしたパス)を使用する場合は、スクリプトが実行されているフォルダが期待通りのものであることを確認してください。
- 指定されたファイルがサブディレクトリ(フォルダの中にあるフォルダ)である場合、FileIsExist関数はfalseを返し、エラーコード5018(これはディレクトリでファイルではありません)が_LastError変数に記録されます。
- MQL5言語では、セキュリティ上の理由からファイルの扱いが厳しく制御されています。ファイルはファイルサンドボックス(特定の制限された領域)内に存在する必要があります。
FileIsExist関数を使ったサンプルコード
以下に、FileIsExist関数を使用してファイルの存在を確認するサンプルコードを示します。
// OnStart関数はスクリプトの実行が開始されたときに自動的に呼び出されます
void OnStart()
{
// チェックするファイルのパスを設定します
string filename = "testfile.txt";
// FileIsExist関数を使用してファイルの存在を確認します
bool fileExists = FileIsExist(filename, FILE_COMMON);
// ファイルの存在確認結果をエキスパートログに出力します
if(fileExists)
{
Print("ファイルが存在します: ", filename);
}
else
{
Print("ファイルが存在しません: ", filename);
}
}
サンプルコードに使われた関数や文法要素の簡単な解説
Print関数
Print関数は、指定したメッセージをエキスパートログに出力するために使用されます。上記のサンプルコードでは、ファイルが存在するかどうかの結果をエキスパートログに出力しています。
if文
if文は条件分岐を行うための構文です。指定した条件がtrueの場合にのみ特定のコードブロックを実行します。上記のサンプルコードでは、ファイルが存在する場合と存在しない場合で異なるメッセージを出力するために使用されています。
FILE_COMMON
FILE_COMMONは、共通のディレクトリ(複数のユーザーがアクセスできるフォルダ)を指定するためのフラグです。すべての端末で共有されるファイルの場所を示します。上記のサンプルコードでは、ファイルの存在確認にこのフラグを使用しています。
公式リファレンスのサンプルコードについて
公式リファレンスFileIsExist関数のサンプルコードは以下のようなものです↓
//--- スクリプトの起動時に入力パラメータのウィンドウを表示する
#property script_show_inputs
//--- 古いファイルの日付
input datetime InpFilesDate = D'2013.01.01 00:00';
//+------------------------------------------------------------------+
//| スクリプトプログラムを開始する関数 |
//+------------------------------------------------------------------+
void OnStart()
{
// ファイル名を格納する変数
string file_name;
// ファイル検索フィルタ
string filter = "*.txt";
// ファイル作成日
datetime create_date;
// ファイル名のリスト
string files[];
// デフォルトの配列サイズ
int def_size = 25;
// ファイル数
int size = 0;
//--- 配列へのメモリ追加
ArrayResize(files, def_size);
//--- ローカルフォルダのルートで検索ハンドルを受け取る
long search_handle = FileFindFirst(filter, file_name);
//--- FileFindFirst() の実行が成功したかをチェックする
if (search_handle != INVALID_HANDLE)
{
//--- ループでファイルを検索する
do
{
// ファイル名を配列に格納する
files[size] = file_name;
//--- 配列サイズを増やす
size++;
if (size == def_size)
{
// 配列サイズを25増やす
def_size += 25;
ArrayResize(files, def_size);
}
//--- エラー値をリセットする
ResetLastError();
//--- 作成日を受け取る
create_date = (datetime)FileGetInteger(file_name, FILE_CREATE_DATE, false);
//--- ファイルが古いかをチェックする
if (create_date < InpFilesDate)
{
// ファイルが古い場合は削除する
PrintFormat("%s file deleted!", file_name);
//--- 古いファイルを削除する
FileDelete(file_name);
}
} while (FileFindNext(search_handle, file_name));
//--- 検索ハンドルを閉じる
FileFindClose(search_handle);
}
else
{
// ファイルが見つからなかった場合の処理
Print("Files not found!");
return;
}
//--- 何のファイルが残っているかをチェックする
PrintFormat("Results:");
// ファイルの存在をチェックするループ
for (int i = 0; i < size; i++)
{
// ファイルが存在するかを確認する
if (FileIsExist(files[i]))
PrintFormat("%s file exists!", files[i]);
else
PrintFormat("%s file deleted!", files[i]);
}
}
```
複雑なので、初学者の方向けにいくつかの区分に分けて解説していきます。
解説1:グローバル領域での記述
//--- スクリプトの起動時に入力パラメータのウィンドウを表示する
#property script_show_inputs
//--- 古いファイルの日付
input datetime InpFilesDate=D'2013.01.01 00:00';
スクリプトの起動時に入力パラメータのウィンドウを表示する
この部分は、スクリプトが起動したときに入力パラメータのウィンドウを表示するための設定を行っています。#property script_show_inputsディレクティブを使用することで、スクリプトが実行される際にユーザーが入力パラメータを設定するウィンドウが自動的に表示されます。
これにより、ユーザーはスクリプト実行前に必要なパラメータを設定することができます。
スクリプトの入力パラメータとして日時を受け取るための変数を定義しています。inputキーワードは、この変数がinput変数であることを示しています。dateTimeは日時を表すデータ型です。
変数名InpFilesDate
は、入力された日付を格納するための変数名です。初期値として2013年1月1日午前0時0分を設定しています。この設定により、スクリプトが実行される際に、この日付以前に作成されたファイルを古いファイルとして扱うことができます。
解説2:OnStart関数の中1
//+------------------------------------------------------------------+
//| スクリプトプログラムを開始する関数 |
//+------------------------------------------------------------------+
void OnStart()
{
string file_name; // ファイル名を格納する変数
string filter = "*.txt"; // ファイル検索フィルタ
datetime create_date; // ファイル作成日
string files[]; // ファイル名のリスト
int def_size = 25; // デフォルトの配列サイズ
int size = 0; // ファイル数
スクリプトプログラムを開始する関数
この部分は、スクリプトプログラムが開始されるときに最初に呼び出される関数を定義しています。OnStart関数は、スクリプトが実行されると自動的に呼び出され、その中に書かれた処理が実行されます。
ファイル名を格納する変数
file_nameは、ファイル名を格納するための変数です。この変数には、検索されたファイルの名前が格納されます。
ファイル検索フィルタ
filterは、ファイル検索のフィルタを設定するための変数です。この場合、フィルタとして*.txtを設定しており、これはテキストファイル(拡張子が.txtのファイル)のみを検索対象とすることを意味します。
ファイル作成日
create_dateは、ファイルの作成日を格納するための変数です。この変数には、各ファイルの作成日時が格納されます。
ファイル名のリスト
filesは、ファイル名のリストを格納するための配列です。この配列には、検索されたすべてのファイル名が格納されます。
デフォルトの配列サイズ
def_sizeは、ファイル名リストの配列の初期サイズを設定するための変数です。最初に配列を作成するときに、このサイズ分のメモリが確保されます。
ファイル数
sizeは、検索されたファイルの数をカウントするための変数です。ファイルが見つかるたびに、この変数の値が増加します。
これらの変数は、スクリプトが実行されるときにファイルを検索し、その情報を処理するために使用されます。
解説3:OnStart関数の中2
//--- 配列へのメモリ追加
ArrayResize(files, def_size);
//--- ローカルフォルダのルートで検索ハンドルを受け取る
long search_handle = FileFindFirst(filter, file_name);
配列へのメモリ追加
ArrayResize関数は、指定された配列のサイズを変更するために使用されます。この行では、ファイル名を格納するための配列filesのサイズをdef_sizeに設定しています。def_sizeは初期値として25が設定されています。これにより、配列には最初に25個分のファイル名を格納するためのメモリが確保されます。
ローカルフォルダのルートで検索ハンドルを受け取る
FileFindFirst関数は、指定されたフィルタに一致する最初のファイルを検索し、そのファイルにアクセスするためのハンドルを返します。
この行では、フィルタとしてfilter変数に設定された*.txtが使用され、最初に見つかったテキストファイルのファイル名がfile_name変数に格納されます。同時に、検索操作に使用するハンドルがsearch_handle変数に格納されます。
解説4:OnStart関数の中3
//--- FileFindFirst() の実行が成功したかをチェックする
if (search_handle != INVALID_HANDLE)
{
//--- ループでファイルを検索する
do
{
files[size] = file_name;
//--- 配列サイズを増やす
size++;
if (size == def_size)
{
def_size += 25;
ArrayResize(files, def_size);
}
//--- エラー値をリセットする
ResetLastError();
//--- 作成日を受け取る
create_date = (datetime)FileGetInteger(file_name, FILE_CREATE_DATE, false);
//--- ファイルが古いかをチェックする
if (create_date < InpFilesDate)
{
PrintFormat("%s file deleted!", file_name);
//--- 古いファイルを削除する
FileDelete(file_name);
}
} while (FileFindNext(search_handle, file_name));
}
FileFindFirstの実行が成功したかをチェックする
search_handleがINVALID_HANDLEと等しくない場合、FileFindFirst関数の実行が成功したことを示しています。これは、少なくとも一つのファイルが検索条件に一致したことを意味します。
ループでファイルを検索する
do-whileループを使用して、条件に一致するすべてのファイルを検索し、それぞれのファイルについて処理を行います。
ファイル名を配列に格納する
files配列の現在のインデックスにfile_nameを格納します。size変数は配列のインデックスを示しており、ファイル名を追加するたびにインクリメントされます。
配列サイズを増やす
sizeがdef_sizeに達した場合、配列のサイズを25増やします。ArrayResize関数を使用して、配列filesのサイズをdef_sizeに設定します。
エラー値をリセットする
ResetLastError関数を使用して、最後に発生したエラーコードをリセットします。これにより、後続のエラーチェックが正確に行われるようになります。
作成日を受け取る
FileGetInteger関数を使用して、現在のファイルの作成日を取得し、create_date変数に格納します。
ファイルが古いかをチェックする
取得した作成日create_dateが、ユーザーが設定したInpFilesDateよりも古い場合、そのファイルを削除対象とします。
古いファイルを削除する
ファイルが古い場合、PrintFormat関数を使用してファイルが削除されることをログに出力し、FileDelete関数を使用して実際にファイルを削除します。
次のファイルを検索する
FileFindNext関数を使用して、次の条件に一致するファイルを検索します。次のファイルが見つかると、do-whileループが続行され、同じ処理が繰り返されます。
検索ハンドルを閉じる
ループが終了したら、FileFindClose関数で検索ハンドルを閉じます。
FileFindClose関数は、検索操作が完了した後、リソースを解放するために必ず呼び出す必要があります。
解説5:OnStart関数の中4
else
{
Print("Files not found!");
return;
}
//--- 何のファイルが残っているかをチェックする
PrintFormat("Results:");
ファイルが見つからなかった場合の処理
検索ハンドルが無効(INVALID_HANDLE)である場合、FileFindFirst関数は条件に一致するファイルを見つけられなかったことを意味します。
- Print関数を使用して、「ファイルが見つかりませんでした!」というメッセージをエキスパートログに出力します。
- returnを使用して、OnStart関数の実行を終了します。これにより、以降の処理は実行されません。
残っているファイルをチェックする
ファイルが見つかった場合の処理が完了した後、残っているファイルが何であるかをチェックするために、PrintFormat関数を使用して「結果:」というメッセージをエキスパートログに出力します。
解説6:OnStart関数の中5
for(int i=0; i<size; i++)
{
if(FileIsExist(files[i]))
PrintFormat("%s file exists!", files[i]);
else
PrintFormat("%s file deleted!", files[i]);
}
}
ファイルの存在をチェックするループ
この部分では、ファイル名が格納されている配列filesをループで回し、それぞれのファイルが存在するかどうかをチェックしています。
- forループは、インデックスをカウントする変数iを0から開始し、size変数(検索されたファイルの数)未満の間、1ずつインクリメントしながら繰り返します。
- 各ループの中で、files配列のi番目の要素(ファイル名)を対象に処理を行います。
ファイルの存在を確認する
FileIsExist関数を使用して、現在のファイルが存在するかどうかをチェックします。
- ファイルが存在する場合は、PrintFormat関数を使用して「[ファイル名] file exists!」というメッセージをエキスパートログに出力します。
- ファイルが存在しない場合は、「[ファイル名] file deleted!」というメッセージをエキスパートログに出力します。
これにより、検索されたすべてのファイルが適切に処理され、それぞれのファイルが存在するかどうかが確認されます。エキスパートログには、各ファイルの状態が出力されるため、ユーザーはファイルの処理結果を確認することができます。