FatFs - f_readdir

## f_readdir

ディレクトリ項目を読み出します。

    FRESULT f_readdir (
      DIR* dp,      /* [IN] ディレクトリ ブジェクト構造体へのポインタ */
      FILINFO* fno  /* [OUT] ファイル情報構造体へのポインタ */
    );

#### 引数

dp
  `f_opendir`関数で作成された有効なディレクトリ オブジェクトへのポインタを指定します。
fno
  読み出したディレクトリ項目を格納するファイル情報構造体へのポインタ、またはヌル ポインタを指定します。

#### 戻り値

FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_INVALID_OBJECT, FR_TIMEOUT, FR_NOT_ENOUGH_CORE

#### 解説

ディレクトリの項目(ファイルおよびサブ ディレクトリ)の情報を順次読み出します。この関数を繰り返し実行することによりそのディレクトリの全ての項目を読み出すことができます。得られるファイル情報の詳細については `FILINFO`構造体を参照してください。全ての項目が読み出され、読み出す項目がもう無いときは、`fno->fname[]`にヌル文字列が返されます。`fno`にヌル ポインタを指定すると、そのディレクトリのリード インデックスを先頭に巻き戻します。サブ ディレクトリのドット エントリ(`"."`と`".."`)は、出力に現れません。

LFN構成では、`altname[]`が新たに定義され、そのオブジェクトの短いファイル名がストアされます。次の条件のときは長いファイル名を返せないので`fname[]`に短いファイル名がストアされ、`altname[]`はヌル文字列になります。

- オブジェクトが長いファイル名を持っていない。(exFATボリュームでは該当せず)
- `_MAX_LFN`の設定がその長いファイル名の長さに対して不十分 (`_MAX_LFN == 255`では該当せず)
- 長いファイル名にANSI/OEMコードに無い文字が含まれている。(`_LFN_UNICODE == 1`では該当せず)

exFATボリュームのディレクトリを読み出すとき、構成によっては問題が発生します。exFATでは短いファイル名がサポートされません。つまり、上記の条件のとき代わりに返すファイル名が無いということです。このような場合は`fname[]`に"?"が返され、そのオブジェクトにアクセスできないことを示します。この問題を避けるには、FatFsの構成を`_LFN_UNICODE = 1`および`_MAX_LFN = 255`として長いファイル名に完全対応とする必要があります。

#### 対応情報

`_FS_MINIMIZE <= 1`のときに使用可能です。

#### 使用例

    FATFS fs;
    char buff[256];

    FRESULT scan_files (
        char* path        /* 開始ノード (ワークエリアとしても使用) */
    )
    {
        FRESULT res;
        DIR dir;
        UINT i;
        static FILINFO fno;

        res = f_opendir(&dir, path);                       /* ディレクトリを開く */
        if (res == FR_OK) {
            for (;;) {
                res = f_readdir(&dir, &fno);                   /* ディレクトリ項目を1個読み出す */
                if (res != FR_OK || fno.fname[0] == 0) break;  /* エラーまたは項目無しのときは抜ける */
                if (fno.fattrib & AM_DIR) {                    /* ディレクトリ */
                    i = strlen(path);
                    sprintf(&path[i], "/%s", fno.fname);
                    res = scan_files(path);                    /* 一つ下へ */
                    if (res != FR_OK) break;
                    path[i] = 0;
                } else {                                       /* ファイル */
                    printf("%s/%s\n", path, fno.fname);
                }
            }
            f_closedir(&dir)
        }

        return res;
    }

    int main (void)
    {
        FRESULT res;

        res = f_mount(&fs, "", 1);
        if (res == FR_OK) {
            strcpy(buff, "/");
            res = scan_files(buff);
        }

        return res;
    }

#### 参照

`f_opendir, f_closedir, f_stat, FILINFO, DIR`

戻る