FileDelete関数の働き・役割
FileDelete関数は、指定されたクライアント端末(ユーザーのコンピュータ)のローカルフォルダ(ユーザーのコンピュータ内のフォルダ)内のファイルを削除するために使用されます。
FileDelete関数を利用することで、特定のファイルを手動で削除する手間を省き、自動的に管理することができます。
FileDelete関数の引数について
FileDelete関数は以下のように定義されています。
bool FileDelete(
const string file_name, // 削除するファイルの名称
int common_flag=0 // 削除するファイルの場所
);
file_name
種類: 文字列
説明: 削除するファイルの名前を指定します。フルパス(ファイルの絶対的な位置を示す完全なパス)ではなく、指定されたフォルダ内のファイル名のみを記述します。
common_flag
種類: 整数(初期値は0)
説明: ファイルの場所を決定するフラグです。common_flagに FILE_COMMON を指定すると、ファイルは全てのクライアント端末(ユーザーのコンピュータ)の共有フォルダ(\Terminal\Common\Files 内)から削除されます。それ以外の場合、ファイルはローカルフォルダ(ユーザーのコンピュータ内のフォルダ)から削除されます。
FileDelete関数の戻り値について
FileDelete関数は、削除が成功した場合はtrueを返し、失敗した場合はfalseを返します。
FileDelete関数を使う際の注意点
- セキュリティ上の理由から、MQL5ではファイルの操作が厳しく制御されています。MQL5で操作されるファイルは、ファイルサンドボックス(安全にファイルを操作するための隔離環境)の外に存在することはできません。
- 指定されたファイルがローカルフォルダ(ユーザーのコンピュータ内のフォルダ)または共有フォルダに存在する必要があります。
FileDelete関数を利用したサンプルコード
以下は、FileDelete関数を利用したサンプルコードになります。
//--- スクリプトの起動時に入力パラメータのウィンドウを表示する
#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のファイル)のみを検索対象とすることを意味します。
アスタリスク(*)はワイルドカード文字(ファイル名や拡張子の一部を指定するために使用される特別な文字)として機能します。
ワイルドカード文字は、ファイル名の一部を任意の文字列に置き換えるために使用されます。具体的には、以下のような文法的な役割を持ちます:
- アスタリスク(*)は、0文字以上の任意の文字列に一致することを意味します。このため、
*.txt
というフィルタは、拡張子が.txt
であるすべてのファイルを検索対象とします。 - 例えば、
document.txt
、report.txt
、notes.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!」というメッセージをエキスパートログに出力します。
これにより、検索されたすべてのファイルが適切に処理され、それぞれのファイルが存在するかどうかが確認されます。エキスパートログには、各ファイルの状態が出力されるため、ユーザーはファイルの処理結果を確認することができます。