readdir_r()

概述:

       1 readdir_r函数,是readdir函数的可重入版本,也就是线程安全的。

       2 readdir函数使用静态数据,因而不可重入,即不是线程安全的。

readdir_r()就是采用局部变量保存数据:

int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);

       The  readdir_r() function returns 0 on success.  On error, it returns apositive error number (listed under ERRORS).  If the end of the  directory  stream  is  reached,  readdir_r()  returns 0, and returns NULL in*result.

readdir_r() 函数是 readdir() 函数可重入版本。

   1 它从目录流dirp 里读取下一个目录项;

   2 通过调用者分配的缓存区 entry返回 ;

   3 返回条目的指针被放置于 *result 里,如果目录流到达结尾,那么把*result 设置为 NULL。当目录被实际读取时,readdir_r()函数将标记目录的st_atime字段的更新

            注:在Linux stat函数中,用st_atime表示文件数据最近的存取时间(last accessed time);用st_mtime表示文件数据最近的修改时间(last modified time);使用st_ctime表示文件i节点数据最近的修改时间(last i-node's status changed time)。这种方式可以避免返回包含空名称的目录项。为每个实际的读操作缓冲多个目录条目;

与readdir区别参考:https://bbs.csdn.net/topics/390491842

        1 readdir()返回的指针可能被统一目录流上 的另一个readdir调用所覆盖,但是不会对另一个目录流上的readdir()调用覆盖。

        2 如果opendir或者rewinddir()之后对目录进行删除或者添加文件,readdir()能否访问到新增减文件是未知的。

        3 调用fork()时,父进程和子进程如果同时调用readdir()、rewinddir()、seekdir(),结果都是是不可预期的。

        4 readdir()使用静态数据,因而不能重入,不能重入的函数也就不是线程安全的。

参考结构:

while(readdir(pDir));

while (!readdir_r(dirp, &entry, &result) && result);

补充说明:


struct dirent {
      ino_t          d_ino;       /* inode number 索引节点号*/
      off_t          d_off;       /* not an offset; see NOTES 在目录文件中的偏移*/
      unsigned short d_reclen;    /* length of this record 文件名长*/
      unsigned char  d_type;      /*type of file; not supported by all  filesystem types 文件类型*/              
                                                                                           
      char           d_name[256]; /* filename 文件名,最长255字符*/
};

d_type的值为:

DT_BLK This is a block device.

DT_CHR This is a character device.

DT_DIR This is a directory.

DT_FIFO This is a named pipe (FIFO).

DT_LNK This is a symbolic link.

DT_REG This is a regular file.

DT_SOCK This is a UNIX domain socket.

DT_UNKNOWN The file type is unknown.

返回值:

         需要检查错误的时候,应该在调用readdir()前对errno设置为0,如果返回时非零,就会报错。

         成功完成后,readdir()将返回指向struct dirent类型对象的指针。当遇到错误时,应返回空指针,并设置errno来指示错误。当遇到目录的末尾时,应返回空指针,并且不更改errno。

            如果成功,readdir_r()函数将返回0;否则,将返回一个错误编号来指示错误。  

example:

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>


static void lookup(const char *arg)
{
    DIR *dirp;
    struct dirent *dp;


    if ((dirp = opendir(".")) == NULL) {
        perror("couldn't open '.'");
        return;
    }


    do {
        errno = 0;//errno 是记录系统的最后一次错误代码。代码是一个int型的值,在errno.h中定义。
        if ((dp = readdir(dirp)) != NULL) {
            if (strcmp(dp->d_name, arg) != 0)
                continue;


            (void) printf("found %s\n", arg);
            (void) closedir(dirp);
                return;


        }
    } while (dp != NULL);


    if (errno != 0)
        perror("error reading directory");
    else
        (void) printf("failed to find %s\n", arg);
    (void) closedir(dirp);
    return;
}


int main(int argc, char *argv[])
{
    int i;
    for (i = 1; i < argc; i++)
        lookup(arvg[i]);
    return (0);
}

使用建议:

1 readdir()函数应该与opendir()、closedir()和rewinddir()一起使用,以检查目录的内容。

2 readdir_r()函数是线程安全的,应该在用户提供的缓冲区中返回值,而不是使用可能被每次调用覆盖的静态数据区域。  

     由于readdir()在检测到错误和遇到目录末尾时返回NULL,因此需要告知差异的应用程序必须在调用之前将errno设置为0,并检查是否返回NULL。由于函数在第二种情况下不能更改errno,并且在第一种情况下必须将其设置为非零值,所以在调用返回NULL后的0值errno表示目录结束。

整理所得,欢迎指正!

1.创建文件夹: #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <iostream> using namespace std; int main() { string folder_name = "new_folder"; mkdir(folder_name.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); //创建文件夹 return 0; } 2.复制文件: #include <stdio.h> #include <stdlib.h> int main() { FILE *fp1, *fp2; //定义两个文件指针 char ch; fp1 = fopen("file1.txt", "r"); //打开要复制的文件 fp2 = fopen("file2.txt", "w"); //打开要复制到的文件 while ((ch = fgetc(fp1)) != EOF) { fputc(ch, fp2); //复制文件 } fclose(fp1); fclose(fp2); return 0; } 3.移动文件: #include <stdio.h> #include <stdlib.h> int main() { char old_path[100] = "old_folder/file1.txt"; char new_path[100] = "new_folder/file1.txt"; int result = rename(old_path, new_path); //移动文件 if (result == 0) { printf("移动成功\n"); } else { printf("移动失败\n"); } return 0; } 4.删除文件夹: #include <unistd.h> #include <stdio.h> int main() { char folder_name[100] = "new_folder"; int result = rmdir(folder_name); //删除文件夹 if (result == 0) { printf("删除成功\n"); } else { printf("删除失败\n"); } return 0; } 5.显示文件夹中的内容: #include <dirent.h> #include <stdio.h> int main() { DIR *dir; struct dirent *ent; char folder_name[100] = "new_folder"; dir = opendir(folder_name); //打开文件夹 while ((ent = readdir(dir)) != NULL) { printf("%s\n", ent->d_name); //遍历文件夹中的文件 } closedir(dir); return 0; } 6.查看文件内容: #include <stdio.h> int main() { FILE *fp; char ch; fp = fopen("file1.txt", "r"); //打开文件 while ((ch = fgetc(fp)) != EOF) { printf("%c", ch); //输出文件内容 } fclose(fp); return 0; } 7.修改文件权限: #include <sys/stat.h> #include <stdio.h> int main() { char file_name[100] = "file1.txt"; chmod(file_name, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); //修改文件权限 return 0; } 8.搜索文件: #include <dirent.h> #include <stdio.h> #include <string.h> int main() { DIR *dir; struct dirent *ent; char folder_name[100] = "new_folder"; char search_name[100] = "file1.txt"; dir = opendir(folder_name); //打开文件夹 while ((ent = readdir(dir)) != NULL) { if (strcmp(ent->d_name, search_name) == 0) //搜索文件 { printf("找到文件:%s\n", ent->d_name); break; } } closedir(dir); return 0; }将上述代码整合成一个完整的程序代码
最新发布
05-31
以下是将上述代码整合成一个完整的程序代码: ``` #include <iostream> #include <dirent.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdlib.h> using namespace std; // 1.创建文件夹 void create_folder() { string folder_name = "new_folder"; mkdir(folder_name.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); //创建文件夹 } // 2.复制文件 void copy_file() { FILE *fp1, *fp2; //定义两个文件指针 char ch; fp1 = fopen("file1.txt", "r"); //打开要复制的文件 fp2 = fopen("file2.txt", "w"); //打开要复制到的文件 while ((ch = fgetc(fp1)) != EOF) { fputc(ch, fp2); //复制文件 } fclose(fp1); fclose(fp2); } // 3.移动文件 void move_file() { char old_path[100] = "old_folder/file1.txt"; char new_path[100] = "new_folder/file1.txt"; int result = rename(old_path, new_path); //移动文件 if (result == 0) { printf("移动成功\n"); } else { printf("移动失败\n"); } } // 4.删除文件夹 void delete_folder() { char folder_name[100] = "new_folder"; int result = rmdir(folder_name); //删除文件夹 if (result == 0) { printf("删除成功\n"); } else { printf("删除失败\n"); } } // 5.显示文件夹中的内容 void show_folder_content() { DIR *dir; struct dirent *ent; char folder_name[100] = "new_folder"; dir = opendir(folder_name); //打开文件夹 while ((ent = readdir(dir)) != NULL) { printf("%s\n", ent->d_name); //遍历文件夹中的文件 } closedir(dir); } // 6.查看文件内容 void show_file_content() { FILE *fp; char ch; fp = fopen("file1.txt", "r"); //打开文件 while ((ch = fgetc(fp)) != EOF) { printf("%c", ch); //输出文件内容 } fclose(fp); } // 7.修改文件权限 void change_file_permission() { char file_name[100] = "file1.txt"; chmod(file_name, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); //修改文件权限 } // 8.搜索文件 void search_file() { DIR *dir; struct dirent *ent; char folder_name[100] = "new_folder"; char search_name[100] = "file1.txt"; dir = opendir(folder_name); //打开文件夹 while ((ent = readdir(dir)) != NULL) { if (strcmp(ent->d_name, search_name) == 0) //搜索文件 { printf("找到文件:%s\n", ent->d_name); break; } } closedir(dir); } int main() { create_folder(); copy_file(); move_file(); delete_folder(); show_folder_content(); show_file_content(); change_file_permission(); search_file(); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值