5.8 文件I/O目录操作和文件属性获取

目录

访问目录 – opendir

访问目录 – readdir

访问目录 – closedir

访问目录-示例代码

修改文件访问权限 – chmod/fchmod

获取文件属性 – stat/lstat/fstat

文件属性 – struct  stat

stat结构体

文件类型-st_mode

文件访问权限-st_mode

笔记


访问目录 – opendir

 opendir函数用来打开一个目录文件:  #include    DIR  *opendir(const char *name);  DIR *fdopendir(int fd);  使用文件描述符,要配合open函数使用 DIR是用来描述一个打开的目录文件的结构体类型 成功时返回目录流指针;出错时返回NULL

访问目录 – readdir

 readdir函数用来读取目录流中的内容:  #include    struct  dirent *readdir(DIR *dirp);   struct dirent是用来描述目录流中一个目录项的结构体类型 包含成员char  d_name[256]   参考帮助文档 成功时返回目录流dirp中下一个目录项; 出错或到末尾时时返回NULL

访问目录 – closedir

 closedir函数用来关闭一个目录文件:  #include    int closedir(DIR *dirp);   成功时返回0;出错时返回EOF

访问目录-示例代码

打印指定的目录下所有文件名称

int  main(int argc, char *argv[]) {
{
    DIR *dirp;
    struct dirent *dp;
    if (argc < 2) {
       printf(“Usage : %s \n”, argv[0]);  return -1;
    }
    if ((dirp  = opendir(argv[1])) == NULL) {
           perror(“opendir”);  return -1;
    }
    while ((dp = readdir(dirp)) != NULL) {
        printf(“%s\n”, dp->d_name);
    }
    closedir(dirp);

修改文件访问权限 – chmod/fchmod

 //chmod/fchmod函数用来修改文件的访问权限:
 #include  
 int  chmod(const char *path, mode_t mode);
 int  fchmod(int fd, mode_t mode);
 
//成功时返回0;出错时返回EOF
//root和文件所有者能修改文件的访问权限
//示例: chmod(“test.txt”, 0666);

获取文件属性 – stat/lstat/fstat

//stat/lstat/fstat函数用来获取文件属性:
 #include  
 int  stat(const char *path, struct stat *buf);
 int  lstat(const char *path, struct stat *buf);
 int  fstat(int fd, struct stat *buf);
  

成功时返回0;出错时返回EOF 如果path是符号链接stat获取的是目标文件的属性;而lstat获取的是链接文件的属性

文件属性 – struct  stat

 struct stat是存放文件属性的结构体类型:

mode_t  st_mode;    类型和访问权限

uid_t  st_uid;   所有者id

uid_t  st_gid;   用户组id

off_t  st_size;   文件大小

time_t  st_mtime;   最后修改时间

stat结构体

struct stat {
    dev_t         st_dev;       //文件的设备编号
    ino_t         st_ino;       //节点
    mode_t        st_mode;      //文件的类型和存取的权限
    nlink_t       st_nlink;     //连到该文件的硬连接数目,刚建立的文件值为1
    uid_t         st_uid;       //用户ID
    gid_t         st_gid;       //组ID
    dev_t         st_rdev;      //(设备类型)若此文件为设备文件,则为其设备编号
    off_t         st_size;      //文件字节数(文件大小)
    unsigned long st_blksize;   //块大小(文件系统的I/O 缓冲区大小)
    unsigned long st_blocks;    //块数
    time_t        st_atime;     //最后一次访问时间
    time_t        st_mtime;     //最后一次修改时间
    time_t        st_ctime;     //最后一次改变时间(指属性)
};

文件类型-st_mode

 通过系统提供的宏来判断文件类型:

S_IFMT      0170000     文件类型的位遮罩

S_ISREG(st_mode)           0100000     是否常规文件

S_ISDIR(st_mode)             0040000    是否目录

S_ISCHR(st_mode)           0020000    是否字符设备

S_ISBLK(st_mode)            0060000    是否块设备

S_ISFIFO(st_mode)           0010000    是否FIFO文件

S_ISLNK(st_mode)            0120000    是否链接文件

S_ISSOCK(st_mode)         0140000    是否SOCKET文件

文件访问权限-st_mode

 通过系统提供的宏来获取文件访问权限:

S_IRUSR           00400                     bit:8    所有者有读权限

S_IWUSR          00200                          7    所有者拥有写权限

S_IXUSR           00100                          6    所有者拥有执行权限

S_IRGRP           00040                          5   群组拥有读权限

S_IWGRP          00020                          4   群组拥有写权限

S_IXGRP           00010                          3   群组拥有执行权限

S_IROTH           00004                          2   其他用户拥有读权限

S_IWOTH          00002                          1   其他用户拥有写权限

S_IXOTH           00001                          0   其他用户拥有执行权限


笔记

打开目录

#include  

 DIR  *opendir(const char *name);

 DIR *fdopendir(int fd);  使用文件描述符,要配合open函数使用

DIR是用来描述一个打开的目录文件的结构体类型

成功时返回目录流指针;出错时返回NULL

读取目录

#include  

 struct  dirent *readdir(DIR *dirp);

struct dirent是用来描述目录流中一个目录项的结构体类型

包含成员char  d_name[256]   参考帮助文档

成功时返回目录流dirp中下一个目录项;

出错或到末尾时时返回NULL

关闭目录

closedir函数用来关闭一个目录文件:

 #include  

 int closedir(DIR *dirp);

成功时返回0;出错时返回EOF

修改文件权限

chmod/fchmod函数用来修改文件的访问权限:

 #include  

 int  chmod(const char *path, mode_t mode);

 int  fchmod(int fd, mode_t mode);

成功时返回0;出错时返回EOF

注意:在vmware和windows共享的文件夹下,有些权限不能改变。

获取文件属性

#include  

 int  stat(const char *path, struct stat *buf);

 int  lstat(const char *path, struct stat *buf);

 int  fstat(int fd, struct stat *buf);

  成功时返回0;出错时返回EOF

如果path是符号链接stat获取的是目标文件的属性;而lstat获取的是链接文件的属性

库的概念:

静态库

创建静态库步骤:

1 . 编写库文件代码,编译为.o 目标文件。

  1. ar 命令 创建  libxxxx.a 文件

   ar -rsv  libxxxx.a  xxxx.o

   注意:1 静态库名字要以lib开头,后缀名为.a

2 没有main函数的.c 文件不能生成可执行文件。

链接错误:

test.c:(.text+0x15):对‘hello’未定义的引用

collect2: error: ld returned 1 exit status

含义:表示hello函数在编译的源码内没有找到实现

解决:实现代码或者找到对应函数的库并且链接它。

链接静态库:

gcc -o 目标文件 源码.c  -L路径  -lxxxx

-L  表示库所在的路径

-l 后面跟库的名称

动态库的生成步骤:

  1. 生成位置无关代码的目标文件

 gcc  -c  -fPIC  xxx.c xxxx.c ....

  1. 生成动态库

   gcc  -shared -o libxxxx.so  xxx.o  xxx.o ....

  1. 编译可执行文件

gcc -o 目标文件 源码.c  -L路径  -lxxxx

执行动态库的可执行文件错误

./test: error while loading shared libraries: libmyheby.so: cannot open shared object file: No such file or directory

含义:可执行文件所使用的动态库找不到

解决办法:

找到动态库,添加到/usr/lib里面

或者使用export  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:你的动态库目录

添加在~/.bashrc 文件里面

使用source ~/.bashrc 生效。

查看可执行文件使用的动态库:

ldd 命令 :   ldd 你的可执行文件

root@haas-virtual-machine:/mnt/hgfs/share/newIOP# ldd test

linux-vdso.so.1 =>  (0x00007fff6548d000)

libmyheby.so => /mnt/hgfs/share/newIOP/day5/libmyheby.so (0x00007f5c89521000)

libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5c89144000)

/lib64/ld-linux-x86-64.so.2 (0x000055fe52211000)

root@haas-virtual-machine:/mnt/hgfs/share/newIOP/day5# ldd test

linux-vdso.so.1 =>  (0x00007ffcb652c000)

libmyheby.so => not found

libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbeeffaf000)

/lib64/ld-linux-x86-64.so.2 (0x0000561003c3b000)

你可能感兴趣的:(c语言,linux,文件IO)