Help us understand the problem. What is going on with this article?

ファイル名,ディレクトリー名をテキストファイルに書き出す

More than 3 years have passed since last update.

やり方は人それぞれですが、新しいものを使いたい

 あるフォルダーにあるファイルをテキストファイルに書き出す場合、これまではHANDLEWIN32_FIND_DATAしか使ったことがありません。他にも方法はたくさんあるのですが、できれば新しいものを使いたいです。

 そこで、マイクロソフトのMSDNから最新の方法を習ってみました。

ファイル走査と書き出す方法

 使用するのは<filesystem>です。まず、これをインクルードしておきます。次に名前空間としてstd::tr2::sys;を追加します。この名前空間にpathを追加して、フォルダーパスを明示します。

 便利なのは、まず以下のMSDNの引用にあるようにstringやwstringに自動変換可能なところでしょうか。

(XP 以降の) Windows のパスは、ネイティブで Unicode で格納されます。path クラスは、自動的にすべての必要な文字列の変換を実行します。 それはワイド文字とナロー文字の両方の配列の引数を受け入れ、UTF8 や UTF16 として書式設定された std::string や std::wstring 型も受け入れます。path クラスは、パスの区切り記号も自動的に正規化します。 コンストラクターの引数のディレクトリの区切り記号として単一のスラッシュを使用することができます。 これにより、Windows と UNIX の両方の環境でのパスの格納に、同じ文字列を使用することができます。

 フォルダー内部のファイル走査方法としてdirectory_iteratorを使用し、ディレクトリ、ファイル、シンボリック リンク、ソケット ファイルなどが検知可能です。

 また、directory_iterator は、項目を directory_entry オブジェクトとして返し、さらに拡張子やファイル名、相対パス、ルートがpath()のメンバー関数、例えばpath().extension()(この場合、拡張子)で自動的に取得できます。

 filesystemの作業としてはMSDNでは以下の項目を想定しているようです。

  • 指定のパスの下のファイルとディレクトリを反復処理
  • ファイルの作成時、サイズ、拡張子、およびルート ディレクトリなどに関するファイルの情報を取得
  • パスの構成、分解、および比較
  • ディレクトリの作成、コピー、および削除
  • ファイルのコピーと削除

例のコード

filename_out.cpp
#include <iostream>
#include <filesystem>
#include <io.h>
#include <fstream>

using namespace std;
namespace nameS = std::tr2::sys;

int main()
{
    nameS::path fPath("C:/folderName/dataFolder"); // folder path

    std::ofstream textFile; // or wofstream. then put "L" before filepath.
    textFile.open("./test.txt", std::ofstream::out | std::ofstream::trunc); // select open mode.out is write,in is read.

    if ((_access("./test.txt",00)) == -1) { // check the file exists or not.00 is return mode.include <io.h>
        cout << "We cannot open the file by error code " << errno << endl; // read error code. 
        system("pause");
        break;
    }

    nameS::directory_iterator itr(fPath), end;
    std::vector<wstring> fileList;
    std::error_code err;

    for (itr; itr != end; itr.increment(err)) {
        if (err != std::errc::operation_not_permitted) {
            auto entry = *itr; // auto = std::experimental::filesystem::v1::path

            fileList.push_back(entry.path()); // add to the vector.
            cout << "file path is " << entry.path() << endl; // output file paths.
            textFile << entry.path().filename() << endl; // put file name in the text file.
        }
        else {
            break;
        }
    }

    textFile.close();

    system("pause");
    return 0;
}
takamon9
C/C++,ATL/MFC,C#(.NET),Python,OpenCv,VBAが得意。他にOpenSSL,ICU,SQL Serverなどを利用したWindowsアプリケーション作成などを嗜む。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away