Linux文件编程3-文件状态

文件状态

函数

文件的状态被储存在一个stat结构体中,它所包含的内容如下:

struct stat{
    mdoe_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_git;     // 文件所有者对应的组
    off_t     st_size;    // 文件的大小字节数
    time_t    st_atime;   // 文件最后被访问的时间
    time_t    st_mtime;   // 文件内容最后被修改的时间
    time_t    st_ctime;   // 文件状态改变的时间
    blksize_t st_blksize; // 文件内容对应的块大小
    blkcnt_t  st_blocks;  // 文件内容对应的块数量
}

我们有三种方法来获取文件状态,他们分别是:


/**
* @description 若文件路径是一个链接的路径,链接所指向文件的信息
* @param path  文件路径
* @param buf   文件状态结构体指针
* @return int  执行成功返回0,执行失败返回-1
*/
int stat(const char *path, struct stat *buf);

/**
* @param fd    文件描述符
* @param buf   文件状态结构体指针
* @return int  执行成功返回0,执行失败返回-1
*/
int fstat(int fd, struct stat *buf);

/**
* @description 若文件路径是一个链接的路径,则获得该链接本身的信息
* @param path  文件路径
* @param buf   文件状态结构体指针
* @return int  执行成功返回0,执行失败返回-1
*/
int lstat(const char *path, struct stat *buf);

演示

为了说明stat和lstat在链接文件上的不同表现,我们在演示目录下创建了"1.txt"和他的链接文件"1.txt.link",目录结构如下:

.
├── 1.txt
├── 1.txt.link -> 1.txt
└── example.cpp
0 directories, 3 files

其中"example.cpp"是我们的示例程序,内容如下:

#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdio.h>

void printFileStat(const char* filePath, const char* linkPath);
void printFileLstat(const char* filePath, const char* linkPath);
void printFileFstat(const int fdf, const int fdl);

int main(void){
    char linkPath[] = "./1.txt.link";
    char filePath[] = "./1.txt";
    int fdf = open(filePath, O_RDONLY);
    int fdl = open(linkPath, O_RDONLY);

    if(fdf==-1){
        printf("Fail to get file fd.\n");
        return -1;
    }
    if(fdl==-1){
        printf("Fail to get link fd.\n");
        return -1;
    }
    printf("file fd:%d, link fd:%d.\n", fdf, fdl);

    printf("=====stat=====\n");
    printFileStat(filePath, linkPath);
    printf("=====lstat=====\n");
    printFileLstat(filePath, linkPath);
    printf("=====fstat=====\n");
    printFileFstat(fdf, fdl);

    if(close(fdf)==-1){
        printf("Fail to close file %s.\n", filePath);
        return -1;
    }

    if(close(fdl)==-1){
        printf("Fail to close file %s.\n", linkPath);
        return -1;
    }

    return 0;
}

void printFileStat(const char* filePath, const char* linkPath){
    struct stat st_file;
    struct stat st_link;

    if(stat(filePath, &st_file)==-1){
        printf("Fail to get the state of file %s\n", filePath);
        return;
    }
    else{
        printf("==>file:\n");
        printf("file length:%ld\nmod time:%ld\nnode:%ld\nmode:%d\n", st_file.st_size, st_file.st_mtime, st_file.st_ino, st_file.st_mode);
    }

    if(stat(linkPath, &st_link)==-1){
        printf("Fail to get the state of file %s\n", linkPath);
        return;
    }
    else{
        printf("==>link:\n");
        printf("file length:%ld\nmod time:%ld\nnode:%ld\nmode:%d\n", st_link.st_size, st_link.st_mtime, st_link.st_ino, st_link.st_mode);
    }
}

void printFileLstat(const char* filePath, const char* linkPath){
    struct stat st_file;
    struct stat st_link;

    if(lstat(filePath, &st_file)==-1){
        printf("Fail to get the state of file %s\n", filePath);
        return;
    }
    else{
        printf("==>file:\n");
        printf("file length:%ld\nmod time:%ld\nnode:%ld\nmode:%d\n", st_file.st_size, st_file.st_mtime, st_file.st_ino, st_file.st_mode);
    }

    if(lstat(linkPath, &st_link)==-1){
        printf("Fail to get the state of file %s\n", linkPath);
        return;
    }
    else{
        printf("==>link:\n");
        printf("file length:%ld\nmod time:%ld\nnode:%ld\nmode:%d\n", st_link.st_size, st_link.st_mtime, st_link.st_ino, st_link.st_mode);
    }
}

void printFileFstat(const int fdf, const int fdl){
    struct stat st_file;
    struct stat st_link;

    if(fstat(fdf, &st_file)==-1){
        printf("Fail to get the state of file, fdf:%d\n", fdf);
        return;
    }
    else{
        printf("==>file:\n");
        printf("file length:%ld\nmod time:%ld\nnode:%ld\nmode:%d\n", st_file.st_size, st_file.st_mtime, st_file.st_ino, st_file.st_mode);
    }

    if(fstat(fdl, &st_link)==-1){
        printf("Fail to get the state of file, fdl:%d\n", fdl);
        return;
    }
    else{
        printf("==>link:\n");
        printf("file length:%ld\nmod time:%ld\nnode:%ld\nmode:%d\n", st_link.st_size, st_link.st_mtime, st_link.st_ino, st_link.st_mode);
    }
}

编译执行后的输出如下:

file fd:3, link fd:4.
=stat=
==>file:
file length:0
mod time:1695094117
node:444
mode:33188
==>link:
file length:0
mod time:1695094117
node:444
mode:33188
=lstat=
==>file:
file length:0
mod time:1695094117
node:444
mode:33188
==>link:
file length:5
mod time:1695094150
node:456
mode:41471
=fstat=
==>file:
file length:0
mod time:1695094117
node:444
mode:33188
==>link:
file length:0
mod time:1695094117
node:444
mode:33188

可以看到

函数特点
stat当输入为链接路径时,输出为链接所指向的文件的状态。
lstat当输入为链接路径时,输出为链接文件本身的状态。
fstat当输入为链接文件描述符时,输出为链接所指向的文件的状态。

另外,基于三个函数执行成功返回0,执行失败返回-1的特点,可以用来判断文件是否存在。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值