linux 文件属性操作及文件结构

在Linux下进行C/C++编程,主要通过以下三个系统调用来获取文件(普通文件,目录,管道,socket,字符,块等)属性。
头文件“#include <sys/stat.h>”
(1) //通过文件名称获取文件属性         int stat(const char *restrict pathname, struct stat *restrict buf); 
(2) //通过文件描述符获取文件属性     int fstat(int filedes, struct stat *buf); 
(3) //通过符号文件名称获取文件属性  int lstat(const char *restrict pathname, struct stat *restrict buf);

返回值(三个函数一样)成功:0 失败:-1
三个系统调用的区别:
1. fstat接受的第一个参数是“文件描述符”,stat和lstat是“文件全路径”,文件描述符需要用调用open之后才能得到,文件全路经直接写即可;

2. lstat获取的是该符号链接本身的信息;而stat获取的是该链接指向的文件的信息;

这三个系统调用都依赖一个重要的结构体struct stat


stat结构体:

struct stat {  
        mode_t     st_mode;       //文件对应的模式,文件,目录等  
        ino_t      st_ino;        //inode节点号  
        dev_t      st_dev;        //设备号码  
        dev_t      st_rdev;       //特殊设备号码  
        nlink_t    st_nlink;      //文件的连接数  
        uid_t      st_uid;        //文件所有者  
        gid_t      st_gid;        //文件所有者对应的组  
        off_t      st_size;       //普通文件,对应的文件字节数  
        time_t     st_atime;      //文件最后被访问的时间  
        time_t     st_mtime;      //文件内容最后被修改的时间  
        time_t     st_ctime;      //文件状态改变时间  
        blksize_t st_blksize;     //文件内容对应的块大小  
        blkcnt_t   st_blocks;     //伟建内容对应的块数量  
      }; 

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>

int main(int argc,char *argv[])
{
    if (argc < 2)
    {
        fprintf(stderr,"usage : %s\n",strerror(errno));
        exit(1);
    }

    struct stat buf;
    if(stat(argv[1],&buf) < 0)
    {
        fprintf(stderr,"stat failed : %s\n",strerror(errno));
        exit(1);
    }

    printf("%s length :%ld\n",argv[1],buf.st_size);
    return 0;
}


判断文件类型的函数:

Linux中七种文件和七种宏:
 普通文件(regular file)              				S_ISREG()
 目录文件(directory file)            			        S_ISDIR()
 块特殊文件(block special file)      	 	        S_ISBLK()
 字符特殊文件(charactor special file)  	        S_ISCHR()
 FIFO(named pipe)                 				S_ISFIFO()         //管道文件
 套接字(socket)                 					S_ISSOCK()
 符号链接(symbolic link)         				S_ISLNK()         //软链接文件

创建软链接文件$ln -s /etc/passwd ./123.so

创建硬链接文件$ln /etc/passwd a

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
//file_type.c
int main(int argc,char *argv[])
{
    if (argc < 2)
    {
        fprintf(stderr,"usage : %s\n",strerror(errno));
        exit(1);
    }

    struct stat buf;
    if (lstat(argv[1],&buf) < 0)
    {
        fprintf(stderr,"stat failed %s\n",strerror(errno));
        exit(1);
    }

    mode_t mode = buf.st_mode;
    if (S_ISREG(mode))
    {
        printf("%s 是普通文件\n",argv[1]);
    }
    else if(S_ISDIR(mode))
    {
        printf("%s 是目录文件\n",argv[1]);
    }
    else if(S_ISBLK(mode))
    {
        printf("%s 是块设备文件\n",argv[1]);
    }
    else if(S_ISLNK(mode))
    {
        printf("%s 是符号链接文件\n",argv[1]);
    }
    return 0;
}


------------------------------------------------------------------------------------------------------------------------------------------------------------

文件权限 9种访问权限位:

S_IRUSR,S_IWUSR,S_IXUSR
S_IRGRP,S_IWGRP,S_IXGRP
S_IROTH,S_IWOTH,S_IXOTH

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc,char *argv[])
{
    if(argc < 2)
    {
        fprintf(stderr,"usage : %s\n",strerror(errno));
        exit(1);
    }
    struct stat st;
    stat(argv[1],&st);

    mode_t mode = st.st_mode;
    if(mode & S_IRUSR)
    {
        printf("r");
    }else
    {
        printf("-");
    }
    if(mode & S_IWUSR)
    {
        printf("w");
    }else
    {
        printf("-");
    }
    if(mode & S_IXUSR)
    {
        printf("x");
    }else
    {
        printf("-");
    }

    if(mode & S_IRGRP)
    {
        printf("r");
    }else
    {
        printf("-");
    }
    if(mode & S_IWGRP)
    {
        printf("w");
    }else
    {
        printf("-");
    }
    if(mode & S_IXUSR)
    {
        printf("x");
    }else
    {
        printf("-");
    }

    if(mode & S_IROTH)
    {
        printf("r");
    }else
    {
        printf("-");
    }
    if(mode & S_IWOTH)
    {
        printf("w");
    }else
    {
        printf("-");
    }
    if(mode & S_IXGRP)
    {
        printf("x");
    }else
    {
        printf("-");
    }
    printf("\n");
    return 0;
}


access函数作用:用于验证实际用户能否访问一个给定的文件
#include <unistd.h>
Int access(const char *pathname,int mode);
返回:成功返回0,出错返回-1。
mode 取值:

R_OK测试读权限
W_OK测试写权限
X_OK测试执行权限
F_OK测试文件是否存在

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main(int argc,char *argv[])
{
    if(argc < 2)
    {
        fprintf(stderr,"usage : %s\n",strerror(errno));
        exit(1);
    }

    if(access(argv[1],R_OK) == 0)
    {
        printf("%s 该文件可读\n",argv[1]);
    }
    else
    {
        printf("%s 该文件不可读\n",argv[1]);
    }
    return 0;
}
权限位的由来
666                                            //创建文件的原始权限
002                                            //掩码值 $umask   

   000 000 010
   111 111 101
 & 110 110 110
 -----------------
   110 110 100

   664

#include <fcntl.h>
//开辟进程,创建文件
int main(void)
{
    creat("a.txt",0644);
    return 0;
}


umask函数
#include <sys/stat.h>
mode_t umask(mode_t mode);
返回:以前的文件模式创建屏蔽字

chmod,fchmod函数
#include <sys/stat.h>
int chmod(const char *pathname,mode_t mode);
int fchmod(int fields,mode_t mode);
返回:成功返回0,出错返回-1。
 想要改变一个文件的权限位,需满足条件:
进程的有效用户ID必须等于文件的所有者ID
进程具有超级用户权限
mode 取值:
S_ISUID,S_ISGID,S_ISVTX
S_IRWXU,S_IRUSR,S_IWUSR,S_IXUSR
S_IRWXG,S_IRGRP,S_IWGRP,S_IXGRP
S_IRWXO,S_IROTH,S_IWOTH,S_IXOTH
    以上参数按位或


chown,fchown,lchown函数
#include <unistd.h>
Int chown(const char *pathname,uid_t owner,gid_t group);
Int fchown(int fieldes,uid_t owner,gid_t group);
Int lchown(const char *pathname,uid_t owner,gid_t group);
返回: 成功返回0,出错返回-1。

限制:
超级用户进程能更改该文件的用户ID
非超级用户满足如下条件可修改文件的组ID
进程拥有该文件
参数owner等于-1或文件的用户ID,并且参数group等于进程的有效组ID或进程 的附加组ID之一

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

int main(void)
{
    system("id");
    system("ls -l a.txt");
    if(chown("a.txt",-1,108) < 0)
    {
        printf("change gid failed\n");
    }
    else
    {
        printf("chage gid success\n");
    }
    system("ls -l a.txt");
    return 0;
}


文件截断函数
#include <unistd.h>
Int truncate(const char *pathname,off_t length);
Int ftruncate(int fieldes,off_t lenght);
返回:成功返回0,出错返回-1。

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

int main(void)
{
    truncate("a.txt",10);
    return 0;
}
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
文件系统结构;





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值