linux下C语言基本的目录操作编程函数简介

目录简介

对于linux文件目录操作函数其实使用命令就能实现,但是其实对于一些命令本质上就是调用系统函数的,比如:madir,umask,chown等命令。


获取文件信息主要函数

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
//不能读取软连接文件
int stat(const char *path, struct stat *buf);
//根据文件描述符读取文件信息
int fstat(int fd, struct stat *buf);
//能读取软连接文件,stat对于软连接,读取到的信息为指向的目标对象
int lstat(const char *path, struct stat *buf);

参数:

  • path:
    文件的路径,即文件名称。
  • buf:
    存储文件信息的一个结构体指针,形式如下:
    struct stat
    {
        dev_t st_dev; //device 文件的设备编号
        ino_t st_ino; //inode 文件的i-node
        mode_t st_mode; //protection 文件的类型和存取的权限
        nlink_t st_nlink; //number of hard links 连到该文件的硬连接数目, 刚建立的文件值为1.
        uid_t st_uid; //user ID of owner 文件所有者的用户识别码
        gid_t st_gid; //group ID of owner 文件所有者的组识别码
        dev_t st_rdev; //device type 若此文件为装置设备文件, 则为其设备编号
        off_t st_size; //total size, in bytes 文件大小, 以字节计算
        unsigned long st_blksize; //blocksize for filesystem I/O 文件系统的I/O 缓冲区大小.
        unsigned long st_blocks; //number of blocks allocated 占用文件区块的个数, 每一区块大小为512 个字节.
        time_t st_atime; //time of lastaccess 文件最近一次被存取或被执行的时间, 一般只有在用mknod、utime、read、write 与tructate 时改变.
        time_t st_mtime; //time of last modification 文件最后一次被修改的时间, 一般只有在用mknod、utime 和write 时才会改变
        time_t st_ctime; //time of last change i-node 最近一次被更改的时间, 此参数会在文件所有者、组、权限被更改时更新
    };

返回值

成功返回0,失败返回-1

函数的主要作用:

  • 这些函数最主要的作用之一是判断文件类型,文件类型与权限存储在st_mode中,可以用以下宏获取文件类型S_ISREG(m)判断文件是否为普通文件,,参数m为结构体中的st_mode成员,若m为宏功能所指对象,则返回真值,不符合为假

    • S_ISDIR(m) 判断文件是否为目录文件
    • S_ISCHR(m) 判断文件是否为字符文件
    • S_ISBLK(m) 判断文件是否为块文件
    • S_ISFIFO(m) 判断文件是否为管道文件
    • S_ISLNK(m) 判断文件是否为符号链接文件
    • S_ISSOCK(m) 判断文件是否为套接字文件
  • 其中st_mode也包含文件的访问权限位,每个文件(包括目录)都有九个访问权限位,如下:

    • S_IRUSR(m) 用户读权限
    • S_IWUSR(m) 用户写权限
    • S_IXUSR(m) 用户可执行权限
    • S_IRWXU(m) 用户读权限,用户写权限,用户可执行权限
    • S_IRGRP(m) 同组读权限
    • S_IWGRP(m) 同组读权限
    • S_IXGRP(m) 同组可执行权限
    • S_IRWXG(m) 同组读权限,同组读权限,同组可执行权限
    • S_IROTH(m) 其他读权限
    • S_IWOTH(m) 其他写权限
    • S_IXOTH(m) 其他可执行权限
    • S_IRWXO(m) 其他读权限,其他写权限,其他可执行权限

函数举例应用

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
    struct stat st;
    int i;
    for(i=1; i<argc; i++)
    {
        if( stat(argv[i],&st) == -1 )
        {
            perror("stat fail\n");
            exit(EXIT_FAILURE);
        }
        if( S_ISREG(st.st_mode) )
        {
            printf("regular file\n");
        }
        else if (S_ISDIR(st.st_mode) )
        {
            printf("direct file\n");
        }
        else if( S_ISCHR(st.st_mode) )
        {
            printf("char file\n");
        }
        else if( S_ISBLK(st.st_mode) )
        {
            printf("block fil\n");
        }
        else 
        {
            printf("noknw file\n");
        }
    }
    return 0;
}

程序运行效果:

root@DESKTOP-FR31BP0:/mnt/e/linuxcode/c/stat# make
gcc -o stat stat.c
root@DESKTOP-FR31BP0:/mnt/e/linuxcode/c/stat# ./stat /tmp
direct file
root@DESKTOP-FR31BP0:/mnt/e/linuxcode/c/stat# ./stat ./stat.c
regular file
root@DESKTOP-FR31BP0:/mnt/e/linuxcode/c/stat#

umask掩码函数

我们都知道在linux下创建一个文件或者目录之后是可以通过chmod等命令进行权限设置,来达到给当前用户、用户组用户以及其他用户分配不同的访问权限。那么,我们新创建的目录和文件本身也是有它的默认权限的,这个默认权限是什么,就是由权限掩码umask所确定的。它的功能可以说与chmod刚好相反的,代表默认拿走的也就是说不要的权限。

函数结构:

#include <sys/types.h>
#include <sys/stat.h>
mode_t umask(mode_t mask);

函数参数:

  • mask
    由刚才所讲的十二个文件访问权限按位或构成的,也可以为一个四位整数,如0777,文件什么权限都没有,0000具有全部权限。
  • 返回值
    总是成功,没有返回失败的参数,返回值总是当前umask的值。

函数应用举例:

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
int main()
{
    umask(0);
    if( creat("a.txt",S_IRWXU|S_IRWXG) == -1 )
    {
        perror("create fail\n");
        exit(EXIT_FAILURE);
    }
    umask(0777);//此时创建的文件什么权限都没有
    system("touch bbbb");
    if( creat("b.txt",S_IRWXO|S_IRWXU) == -1 )
    {
        exit(EXIT_FAILURE);
    }
    return 0;
}

chmod,fchmod,改变文件权限

#include <sys/stat.h>
int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);

函数参数

  • mode
    同上
  • 返回值
    成功返回0 ,出错返回-1

函数应用举例

#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc,char * argv[])
{
    struct stat st;

    if( stat(argv[1],&st) == -1 )
    {
        perror("stat fail\n");
        exit(EXIT_FAILURE);
    }
    system("ls -l ji");    
    chmod(argv[1],st.st_mode | S_IXOTH ); 
    system("ls -l ji");
    chmod(argv[1],st.st_mode&(~S_IWUSR));
    system("ls -l ji");
    return 0;
}

chown,fchown,改变文件用户ID与组ID

#include <unistd.h>
int chown(const char *path, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
int lchown(const char *path, uid_t owner, gid_t group);

应用举例:

//只有超级用户才能进行更改文件所属人
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char * argv[])
{
    struct stat st;
    if( stat(argv[1],&st) == -1 )
    {
        perror("stat fail\n");
        exit(EXIT_FAILURE);
    }
    printf("uid:%d,gid:%d\n",st.st_uid,st.st_gid);
    system("ls -l ji");
    chown(argv[1],(uid_t)0,(gid_t)0);
    stat(argv[1],&st);
    printf("uid:%d,gid:%d\n",st.st_uid,st.st_gid);
    system("ls -l ji");
    return 0;
}

mkdir 创建目录

#include <sys/stat.h>
 #include <sys/types.h>
 int mkdir(const char *pathname, mode_t mode);

参数:

  • pathname
    带路径的目录名称
  • mode
    创建文件的权限,与umask有关。应该至少要设置以为可执行权限位。这样才能访问该目录的内容。

返回值
成功返回0 ,失败返回-1.


应用举例:

#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
int main()
{
    mkdir("./dir",0777);
    return 0;
}

代码运行效果

root@DESKTOP-FR31BP0:/mnt/e/linuxcode/c/stat# make
gcc -o stat stat.c
root@DESKTOP-FR31BP0:/mnt/e/linuxcode/c/stat# ./stat
root@DESKTOP-FR31BP0:/mnt/e/linuxcode/c/stat# ls
dir  Makefile  stat  stat.c
root@DESKTOP-FR31BP0:/mnt/e/linuxcode/c/stat# ls -l dir/
总用量 0
drwxrwxrwx 0 root root 4096 418 14:46 dir
-rwxrwxrwx 1 root root   34 418 14:02 Makefile
-rwxrwxrwx 1 root root 8600 418 14:46 stat
-rwxrwxrwx 1 root root  196 418 14:46 stat.c
root@DESKTOP-FR31BP0:/mnt/e/linuxcode/c/stat#

opendir打开目录

#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
DIR *fdopendir(int fd);

功能

  • 打开目录

参数

  • name;带路径的目录名
  • fd:目录ID

返回值

  • DIR*形态的目录流,接下来对目录的读取和搜索都要使用此返回值,类似文件打开会返回fd,作为open,read等的索引,这里返回的是DIR指针

DIR结构体

    struct __dirstream  
    {  
    void *__fd; /* `描述符的struct hurd_fd'指针   */  
    char *__data; /* 目录块。   */  
    int __entry_data; /* 条目号   */  
    char *__ptr; /* 当前指向该块的指针。*/  
    int __entry_ptr; /* 条目号   */  
    size_t __allocation; /* 分配给块的空间。   */  
    size_t __size; /* 块中的总有效数据。  */  
    __libc_lock_define (, __lock) /* 此结构的互斥锁。  */  
    };  
    typedef struct __dirstream DIR;  

readdir读取目录

#include <dirent.h>
struct dirent * readdir(DIR * dir);

功能

  • 从指定的drip目录指针中获取一次当前目录中的文件信息

参数

  • dir要读的目录指针

返回值

  • 成功则返回struct dirent结构体指针 有错误发生或读取到目录文件尾则返回NULL

struct 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字符 */  

/*
    对于d_type:
    DT_BLK:块设备
    DT_CHR:字符设备
    DT_DIR:目录
    DT_LNK:软连接
    DT_FIFO:管道
    DT_REG:普通文件
    DT_SOCK:套接字文件
    DT_UNKNOWN:未知
    */
    }  

 closedir关闭目录

#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);

功能

  • 关闭目录

参数

  • dirp:目录的描述指针

返回值

关闭成功则返回0,,失败返回-1,,错误原因存于errno


remove删除函数

#include <stdio.h>
int remove(const char *pathname);

功能

  • 删除指定路径的文件或目录

参数

  • pathname:文件名或目录路径,filename为要删除的文件名,也可以为一目录。如果参数filename为一文件,则调用unlink()处理;若参数filename为目录,则调用rmdir()来处理,且该目录必须为空。

返回值

  • 成功则返回0,失败则返回-1,错误原因存于errno

补充

int rmdir(const char *pathname);
//使用rmdir()函数时,目录必须为空,否则调用失败,函数返回-1.成功时,函数返回0
int unlink(const char *pathname);

小实验:读取文件夹下普通文件的内容

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

int get_file_num(char *root)
{
    int total=0;
    DIR* dir=NULL;
    struct dirent* dirent;
    dir=opendir(root);
    if(dir==NULL)
    {
        perror("opendir");
        exit(1);
    }
    while((dirent=readdir(dir))!=NULL)
    {
        if( (strcmp(".",dirent->d_name)==0 || strcmp("..",dirent->d_name)==0) )
        {
            continue;
        }
        if( dirent->d_type == DT_REG ) 
        {
            total++;
            printf("file name is %s\n",dirent->d_name);
        }
        if( dirent->d_type == DT_DIR )
        {
            char path[1024]={0};
            sprintf(path,"%s/%s",root,dirent->d_name);
            total+=get_file_num(path);
        }
    }
    closedir(dir);
    return total;
}
int main(int argc,char *argv[])
{
    int sourcenum;
    sourcenum = get_file_num(argv[1]);
    printf("file num is %d\n",sourcenum);
    return 0;
}

程序运行效果:

root@thinkpad:/zhang/codefiles# ./a.out /root
file name is .bashrc
file name is accels
file name is user
file name is .viminfo
file name is recently-used.xbel
file name is .bash_history
file name is 9d35ab44d48248f2a61cf41d713e89a2-0
file name is .vimrc
file name is .profile
file num is 9
root@thinkpad:/zhang/codefiles# ls /root/ -a
.  ..  .bash_history  .bashrc  .cache  .config  .dbus  .local  .profile  .viminfo  .vimrc
root@thinkpad:/zhang/codefiles# 

猜你喜欢

转载自blog.csdn.net/z961968549/article/details/80037049
今日推荐