LoginSignup
0
1

More than 5 years have passed since last update.

C++ Builder XE4 > fileIO > linux:find -maxdepth相当の処理をC++ Builderで実装する

Last updated at Posted at 2018-12-11
動作環境
C++ Builder XE4

ファイル探索の問題

  • 下層にたくさんのフォルダがあるフォルダで、ファイル探索をすると処理が返るまで時間がかかる

これを回避するため、「フォルダ階層数」に上限を設けた探索を検討する。

処理概要

ファイル、フォルダ構造

ファイル、フォルダ構図のマインドマップ
https://atlas.mindmup.com/yasokada/_181211/index.html

下記は、上記の画像

2018-12-11_11h43_58.png

フォームデザイン

2018-12-11_11h46_47.png

実装

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

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include "cspin.h"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE で管理されるコンポーネント
    TMemo *Memo1;
    TLabel *Label1;
    TButton *B_search;
    TEdit *E_depth;
    void __fastcall B_searchClick(TObject *Sender);
private:    // ユーザー宣言
    String __fastcall findFileInDir_maxdepthOf(String baseDir, String filePattern, int maxdepth);
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 link "cspin"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    Memo1->Lines->Clear();
    E_depth->Text = L"1";
}
//---------------------------------------------------------------------------

String __fastcall TForm1::findFileInDir_maxdepthOf(String baseDir, String filePattern, int maxdepth)
{
    // 同じファイルが複数のフォルダにある場合、上位のフォルダのファイルが探索にひっかかる設計
    //

    // 1. ファイルの探索
    TSearchOption filOpt = TSearchOption::soTopDirectoryOnly;
    TStringDynArray fileList = TDirectory::GetFiles(baseDir, filePattern, filOpt);
    if (fileList.Length > 0) {
        return fileList[0];
    }

    if (maxdepth <= 1) {
        return L"";  // not found
    }

    // 2. フォルダの探査
    TStringDynArray dirList;
    TSearchOption dirOpt = TSearchOption::soTopDirectoryOnly;

    dirList = TDirectory::GetDirectories(baseDir, L"*", dirOpt);

    for(int idx=0; idx < dirList.Length; idx++) {
        String res = findFileInDir_maxdepthOf(dirList[idx], filePattern, (maxdepth-1));
        if (res.Length() > 0) {
            return res;
        }
    }

    return L"";  // not found
}
void __fastcall TForm1::B_searchClick(TObject *Sender)
{
    // 実行ファイル.exeがあるフォルダをベースとする
    String baseDir = ExtractFileDir(Application->ExeName);
    String filPtrn = L"*.csv";  // ファイル名パターン
    int depth = E_depth->Text.ToInt();

    String res = findFileInDir_maxdepthOf(baseDir, filPtrn, depth);
    if (res.Length() == 0) {
        res = L"[NOT FOUND]";
    }


    String msg = L"depth=" + IntToStr(depth) + L":" + res;
    Memo1->Lines->Add(msg);
}
//---------------------------------------------------------------------------

動作例

上記画像の再掲
2018-12-11_11h43_58.png

動作例
2018-12-11_11h41_46.png

備考

  • 同じファイルが複数フォルダにある場合、上位フォルダのファイルが探索にひかっかる
  • 下層フォルダにあるファイルが探索にひっかかってほしい場合は、探索方法の変更が必要
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1