Linux编程目录操作

对于linux文件目录操作函数其实使用命令就能实现,但是其实对于一些命令本质上就是调用系统函数的,比如:madir,umask,chown等命令。所以此篇博客就对文件目录操作的系统函数进行一下总结。

(1)stat,fstat,fstatat 获取文件信息
   #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);
   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 判断文件是否为普通文件
  • S_ISDIR 判断文件是否为目录文件
  • S_ISCHR 判断文件是否为字符文件
  • S_ISBLK 判断文件是否为块文件
  • S_ISFIFO 判断文件是否为管道文件
  • S_ISLNK 判断文件是否为符号链接文件
  • S_ISSOCK 判断文件是否为套接字文件

其中st_mode也包含文件的访问权限位,每个文件(包括目录)都有九个访问权限位,如下:

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

例如:

#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;
}
(2)umask 为进程设置文件模式创建屏蔽字,简单的将该函数可以指定创建文件的权限。
   #include <sys/types.h>
   #include <sys/stat.h>
  • 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;
}
(3)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;
}
(4)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;
}
(5)truncate,截断文件至指定长度。
  #include <unistd.h>
  #include <sys/types.h>
  int truncate(const char *path, off_t length);
  int ftruncate(int fd, off_t length);
  • 返回值:成功返回0 ,出错返回-1.

例如:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
int main(int argc,char * argv[])
{
    system("ls -l ji");

    if( truncate(argv[1],20) == -1 )
    {
        perror("truncate  err\n");
        exit(EXIT_FAILURE);
    }

    system("ls -l ji");
    return 0;
}
  #include <unistd.h>
  • oldpath : 源文件名
  • newpath :新的连接文件名
  • 返回值:成功返回0 ,出错返回-1.

例如:

#include  <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc,char * argv[])
{
    if( access(argv[1],F_OK) == -1 )
    {
        perror("file  not  exit!\n");
        exit(EXIT_FAILURE);
    }

    if( link(argv[1],"newfile")  == -1 )
    {
        perror("create link err\n");
        exit(EXIT_FAILURE);
    }

    return 0;
}
(7)mkdir,创建新的目录
 #include <sys/stat.h>
 #include <sys/types.h>
 int mkdir(const char *pathname, mode_t mode);
  • pathname: 要创建的目录名称
  • mode : 创建文件的权限,与umask有关。应该至少要设置以为可执行权限位。这样才能访问该目录的内容。
  • 返回值: 成功返回0 ,失败返回-1.
(8)opendir,打开目录
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
  • 其中返回值是一个DIR类型的指针。若失败返回NULL.
(9)readdir 读取该目录文件中的文件
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
  • 返回struct dirent类型的指针

例如:

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
int main(int argc,char *argv[])
{
    DIR * dp = NULL;
    struct stat st;
    struct dirent *dirp = NULL;
    if( (dp = opendir(argv[1])) == NULL)
    {
        perror("opendir err\n");
        exit(EXIT_FAILURE);
    }
    while( (dirp = readdir(dp)) != NULL )
    {
        if( stat(dirp->d_name,&st) == -1 )
        {
            perror("stat err\n");
            exit(EXIT_FAILURE);
        }
        printf("%d %12d %12d %12d %20s\ %12s \n",st.st_nlink,st.st_uid,st.st_gid,st.st_size,asctime(localtime(&(st.st_ctime))),dirp->d_name);
    }

    return 0;
}
(9)unlink,如果文件连接数为1,则直接删除该文件,如果大于1,则删除该文件名,并使得该文件的连接数减去1.
   #include <unistd.h>
   int unlink(const char *pathname);
  • 返回值: 成功返回0 ,否者返回 -1.

例如:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc,char * argv[])
{
    if( unlink(argv[1]) < 0)
    {
        printf("unlink err\n");
        exit(EXIT_FAILURE);
    }

    return 0;
}
(10)chdir,改变当前进程的当前工作目录,只影响该进程
   #include <unistd.h>
   int chdir(const char *path);
   int fchdir(int fd);
  • 返回值: 成功返回0 ,否者返回 -1。
(11)getcwd ,由于内核只为每个进程保存该目录的v节点的指针,等目录本身的信息,而不不保存目录的完整路径,所有要想获得当前进程的完整路径,需要用getcwd函数。
   #include <unistd.h>
   char *getcwd(char *buf, size_t size);
   char *get_current_dir_name(void);//获得当前路径
  • buf :用于存放完整路径名的数组
  • size:该数组的长度。该长度必须能容纳完整路径名长度加1,加一因为最后有个null字符
  • 返回值: 成功返回buf指针,否则返回NULL.

例如:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define SIZE  100
int main(int argc,char * argv[])
{
    char buff[SIZE];

    if( getcwd(buff,SIZE) == NULL )
    {
        perror("getced  err\n");
        exit(EXIT_FAILURE);
    }
    printf("%s\n",buff);

    printf("%s\n",get_current_dir_name());
    return 0;
}

好了。对于目录的操作也就总结完了,虽然只是进行了简单的对每个函数进行讲解,但感觉还是受益匪浅,特别是基本上每个函数都有一个例子,清晰的表明函数了函数的用法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值