c++ builder XE4, 10.2 Tokyo > fileIO > 指定日付以降のファイルをフォルダ単位でコピーする実装


動作環境
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2018/01/09)

関連 http://qiita.com/7of9/items/082de92a61432592923c

指定日付以降のファイルだけフォルダ単位でコピーするfolderCopyWithStartDateTime()を実装した。

Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE で管理されるコンポーネント
    TButton *Button1;
    void __fastcall Button1Click(TObject *Sender);
private:    // ユーザー宣言
public:     // ユーザー宣言
    __fastcall TForm1(TComponent* Owner);
};


//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <IOUtils.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------

static int __fastcall folderCopyWithStartDateTime(String srcBaseDir, String dstBaseDir, TDateTime startDt)
{
    // サブフォルダも含めてコピーする

    String searchPattern = L"*.*";
    TSearchOption option = TSearchOption::soAllDirectories;

    TStringDynArray fileList = TDirectory::GetFiles(srcBaseDir, searchPattern, option);
    String fromStr, toStr;
    String toDir;
    TDateTime filedt;
    int cnt = 0;
    for(int idx = 0; idx < fileList.Length; idx++) {
        filedt = TFile::GetLastWriteTime(fileList[idx]);
        if ( filedt < startDt ) {
            continue;
        }

        fromStr = fileList[idx];
        toStr = StringReplace(fromStr, srcBaseDir, dstBaseDir, TReplaceFlags()<<rfReplaceAll);

        toDir = ExtractFileDir(toStr);
        if (DirectoryExists(toDir) == false) {
            ForceDirectories(toDir);
        }

        try {
            TFile::Copy(fromStr, toStr, /*overwrite=*/true);
            cnt++;
        } catch (...) {
        }
    }

    return cnt;
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    String fromDir = L"D:\\TMP\\160718_someData\\From";
    String toDir = L"D:\\TMP\\160718_someData\\To";

    DWORD start = GetTickCount();

    int copied = folderCopyWithStartDateTime(fromDir, toDir, VarToDateTime("2016/05/24 12:00") );

    DWORD elapsed_msec = GetTickCount() - start;


    String msg = IntToStr(copied) + L" copied in " + IntToStr((int)elapsed_msec) + L" msec";
    OutputDebugString(msg.c_str());
}
//---------------------------------------------------------------------------
結果
デバッグ出力: 177 copied in 515 msec プロセス Project1.exe (932)

上記処理を定期的に行う場合、コピーされるファイル数はほぼ一定になると思われる。一方でコピー元フォルダのファイル数は増えていくので、そのファイル数増加による処理時間の増加がどれくらい増えるだろうか。

試しにコピー元フォルダに2013年ころのファイル1730個(1.4GB)追加してみたが、コピーは250msecで終了した。

さらにコピー元フォルダに2012年ころのファイル9250個(1.4GB)を追加してみたが、コピーは512msecで終了した。この程度の処理時間が維持できればとりあえずはOKとしよう。