Linux ファイル/ディレクトリ アクセス (opendir/closedir/readdir)

Linux システムでは、特定のディレクトリ内のすべてのファイルとディレクトリ (フォルダー) へのアクセスを容易にする必要があります。

Linux でディレクトリ ファイルを取得するプロセスは次のとおりです。

1. 指定したディレクトリを開き、opendir を使用してディレクトリ ハンドルを取得します。

2. while ループで readdir を使用してディレクトリの内容を取得し、それを struct dirent 構造変数に格納します。

3. dirent 構造変数は、ファイル/フォルダーのいくつかの属性を格納し、これらの属性を介していくつかの差別化された操作を実行できます。

4. 最後に、ディレクトリ ハンドル closedir を閉じます。

関数のプロトタイプと構造体

opendir原型:

DIR *opendir(const char *path);

返回值:NULL  打开目录失败
readdir原型:

struct dirent *dir_entry;    //存储获取的目录内容

struct dirent *readdir(DIR *dirp);

返回值:NULL说明获取目录内容失败或者目录内容已经全部读取完成 ;
closedir原型:

int closedir(DIR *dirp);

返回值:0正常 -1错误

ヘッダー ファイル <sys/stat.h>、<dirent.h> が必要です

dirent结构体内容:

struct dirent
{
   long d_ino; /* inode number 索引节点号 */
   off_t d_off; /* offset to this dirent 在目录文件中的偏移 */
   unsigned short d_reclen; /* length of this d_name 文件名长 */
   unsigned char d_type; /* the type of d_name 文件类型 */
   char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
}

dirent 構造体で一般的に使用される 3 つの変数は、d_reclen、d_type、および d_name です。

d_reclen はファイル名の長さを示し、6 は . で始まるサブディレクトリまたは隠しファイルを示し、24 は通常のテキスト ファイルを示し、28 はバイナリ ファイルを示し、32 はフォルダを示します。

d_type は現在のタイプを示し、値は 4 でこれがフォルダーであることを示し、値 8 はこれがファイルであることを示します。

d_name は、現在のファイル/フォルダーの名前を表します。

 

DIR 结构体内容:

struct __dirstream
{
void *__fd; /* `struct hurd_fd' pointer for descriptor.   */
char *__data; /* Directory block.   */
int __entry_data; /* Entry number `__data' corresponds to.   */
char *__ptr; /* Current pointer into the block.   */
int __entry_ptr; /* Entry number `__ptr' corresponds to.   */
size_t __allocation; /* Space allocated for the block.   */
size_t __size; /* Total valid data in the block.   */
__libc_lock_define (, __lock) /* Mutex lock for this structure.   */
};
typedef struct __dirstream DIR;

DIR 構造体の内容はほとんど問題になりません。 

ルーティーン

パスを指定して、そのパスの下の有効なファイルをトラバースするには、次のようにします。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <dirent.h>
#include <sys/types.h>

void getDir(){
    //传入一个有效路径
    std::string path = "/Users/fileTest";
    struct stat sb;
    //判断该路径是否是目录
    if(stat(path.c_str(),&sb)!=0||!S_ISDIR(sb.st_mode)){
        return;
    }
    struct dirent* ent = nullptr;
    DIR *pDir = nullptr;
    pDir = opendir(path.c_str());
    while (nullptr != (ent=readdir(pDir))) {
        //文件夹里默认存在.和..,直接跳过
        if(strcmp(ent->d_name,".")==0||strcmp(ent->d_name,"..")==0) continue;
        //如果是一个文件夹
        if (ent->d_reclen == 32) {
            std::cout<<"folder:"<<ent->d_name<<std::endl;
        }else{//如果是一个文件
            std::cout<<"file:"<<ent->d_name<<std::endl;
        }
    }
    closedir(pDir);
}

int main(int argc, const char * argv[]) {
    // insert code here...
    getDir();
    return 0;
}

注意点の 1 つは、. と .. がデフォルトで Unix およびすべての Unix 系システムのフォルダーに生成され、. が現在のフォルダーを表し、.. が現在のフォルダーの親フォルダーを表すことです。通常、2 つの隠しフォルダーは必要ないため、トラバース時にそれらを直接スキップします。

また、パスを渡す場合、そのパスが正当なディレクトリであるかどうかを判断する必要があるため、追加の判断が必要です。

おすすめ

転載: blog.csdn.net/m0_37872216/article/details/126972644