執筆バージョン: Unreal Engine 5.5
|
こんにちは!今回は、書き込み中のファイルをコピーしてみようと思います。
「書き込み中のファイル?」とピンとこない方もいらっしゃるかもしれません。
例えば、なにかしらのプロセスが記録中の「ログファイル」を
「記録処理を止めずにその場でコピーしてあれこれしたい」
などという場合に今回の記事が役に立つかと思います。
そう、例えば、実行中の Unreal Editor のログとか。
さて、まずは、普通にログファイルをコピーしてみましょう。
Blueprint でファイルをコピーするには、UEに含まれるプラグイン「Blueprint File Utilities」が便利です。
エディタのメニュー [Edit] – [Plugins] で探して有効化してみましょう。
「Unreal Editor を再起動してね」というメッセージが出るので、[Restart Now] をクリックしてエディタを再起動します。
これで準備ができました。
試しに、空レベルを作成してレベルブループリントを開き、以下のようなノードを作ってみましょう:

CopyFile ノードのピンは、上が「コピー先」ファイルパス、下が「コピー元」ファイルパスなのでご注意を。
Unreal Editor のログファイルは プロジェクトのルート/Saved/Logs/プロジェクト名.log に
生成されているので、GetProjectSavedDirectory ノードを使って指定します。
このとき、図のように Combine ノードを使うと、String 配列の各要素を、 スラッシュを挟んだ形になるよう結合してくれます。
さて、このレベルを実行すると、コピーに成功したかどうか、画面左上に Print されるはず。
おっと。
“false” つまり、失敗したとのこと。
実際、エクスプローラなどで見ても、ファイルがコピーされていません。
Unreal Editor のログファイルは今まさに書き込まれている最中で どうやらこのままではコピーさせてくれないようです。
それでは、CopyFile ノードで何をしているか、ソースコードを覗いてみましょう:
|
// BlueprintFileUtilsBPLibrary.cpp bool UBlueprintFileUtilsBPLibrary::CopyFile(const FString& DestFilename, const FString& SrcFilename, bool bReplace /*= true*/, bool bEvenIfReadOnly /*= false*/) { return IFileManager::Get().Copy(*DestFilename, *SrcFilename, bReplace, bEvenIfReadOnly) == COPY_OK; } |
IFileManager::Get().Copy() を呼ぶだけのコードとなっています。
IFileManager::Get() の中身を見てみると、FFileManagerGeneric を返しているので
実際に呼ばれている関数は FFileManagerGeneric::Copy() のようです。
では、 FFileManagerGeneric::Copy() はどうなっているでしょうか。
|
// FileManagerGeneric.hpp CORE_API virtual uint32 Copy( const TCHAR* Dest, const TCHAR* Src, bool Replace = 1, bool EvenIfReadOnly = 0, bool Attributes = 0, FCopyProgress* Progress = nullptr, EFileRead ReadFlags = FILEREAD_None, EFileWrite WriteFlags = FILEWRITE_None ) override; |
UBlueprintFileUtilsBPLibrary::CopyFile() 内で指定している引数よりも、指定可能な引数が多いですね!
その中にある EFileRead ReadFlags = FILEREAD_None が今回のポイントです。
ここで FILEREAD_None ではなく FILEREAD_AllowWrite を指定すると
「別プロセスからのファイルの書き込み中に、ファイルを読み取る」ことができます。
というわけで、UBlueprintFileUtilsBPLibrary::CopyFile() をアレンジした関数を作って検証してみましょう:
|
// MyBlueprintFunctionLibrary.h UFUNCTION(BlueprintCallable) static bool CopyFileWithReadAllowWrite(const FString& DestFilename, const FString& SrcFilename, bool bReplace /*= true*/, bool bEvenIfReadOnly /*= false*/); |
|
// MyBlueprintFunctionLibrary.cpp bool UMyBlueprintFunctionLibrary::CopyFileWithReadAllowWrite(const FString& DestFilename, const FString& SrcFilename, bool bReplace /*= true*/, bool bEvenIfReadOnly /*= false*/) { return IFileManager::Get().Copy( *DestFilename , *SrcFilename , bReplace , bEvenIfReadOnly , /*bool Attributes*/ false , /*FCopyProgress * Progress*/ nullptr , FILEREAD_AllowWrite ) == COPY_OK; } |
ビルドしたら、レベルブループリントの CopyFile ノードを CopyFileWithReadAllowWrite に置き換えます。

それでは、実行してみましょう!

成功しましたね! エクスプローラでも確認してみると

無事に、実行中の Unreal Editor のログファイルがコピーされました!