获取文件属性/库Lib

news2024/12/23 2:58:24

获取文件属性

  1. stat 函数

  man 2 stat

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int stat(const char *path, struct stat *buf);
功能:获取文件属性
参数:  path:文件路径名
       buf:保存文件属性信息的结构体
返回值:成功:0
      失败:-1

struct stat {
        ino_t     st_ino;     /* inode号 ls -il */     
        mode_t    st_mode;    /* 文件类型和权限 */
        nlink_t   st_nlink;   /* 硬链接数 */
        uid_t     st_uid;     /* 用户ID */
        gid_t     st_gid;     /* 组ID */
        off_t     st_size;    /* 大小 */
        time_t    st_atime;   /* 最后访问时间 */
        time_t    st_mtime;   /* 最后修改时间 */
        time_t    st_ctime;   /* 最后状态改变时间 */
    };

文件权限和类型需要通过位操作获取:

st_mode 主要包含了 3 部分信息:

a. 15bit ~ 12bit 保存文件类型

b. 11bit ~ 9bit 保存执行文件时设置的信息(不用管)

c. 8bit ~ 0bit 保存文件访问权限

  1. 获取文件类型

S_IFMT是一个掩码,它的值是0170000(注意这里用的是八进制前缀为0二进制0b001111000000000000), 可以用来把st_mode位与上掩码过滤提取出表示的文件类型的那四位(15bit~12bit位),也就是这四位原样获取其他位清零。

man 7 inode查看(18版本)

这四位可以表示0b0000~0b1111(八进制表示:001~014)七个值,每个值分别对应不同的文件类型:套接字文件、符号链接文件、普通文件、块设备、目录、字符设备、管道。

判断一个文件是不是普通文件,首先通过掩码S_IFMT把其他无关的部分置0,再与表示普通文件的数值比较,从而判断这是否是一个普通文件:

解释:

也可以用swich:

练习:

       用标准IO实现cp功能

#include <stdio.h>
int main(int argc, char const *argv[])
{
    FILE *fp1, *fp2;
    char buf[32];
    if (argc != 3)
    {
        printf("err: %s <srcfile> <destfile>\n", argv[0]);
        return -1;
    }

    fp1 = fopen(argv[1], "r");
    if (NULL == fp1)
    {
        perror("fopen fp1 err");
        return -1;
    }

    fp2 = fopen(argv[2], "w");
    if (NULL == fp2)
    {
        perror("fopen fp2 err");
        return -1;
    }

    while (fgets(buf, 32, fp1) != NULL)
    {
        fputs(buf, fp2);
    }
    // char ch;
    // while ((ch = fgetc(fp1)) != EOF)
    // {
    //     fputc(ch, fp2);
    // }

    fclose(fp1);
    fclose(fp2);

    return 0;
}
  1. 获取文件权限

0-8bit位每一位表示一个权限,所以只需要把这一位位与出来就可以判断是否有这个权限,为1说明有,为0说明没有。

比如判断个人权限是否有可读: st.st_mode&0b000000100000000(八进制:00400)

也就是利用宏: st.st_mode&S_IRUSR

解释:

练习:编程实现“ls -l 文件名”功能

getpwuid

getgrgid

localtime或ctime

ctime函数在C库中,头文件为<time.h>

函数原型:

char *ctime (const time_t *__timer)

作用:返回一个表示当地时间的字符串,当地时间是基于参数 timer

格式例如: Wed Aug 29 19:48:54 2018

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>

int main(int argc, char const *argv[])
{
    struct stat st;

    if (stat(argv[1], &st) < 0)
    {
        perror("stat err");
        return -1;
    }

    switch (st.st_mode & S_IFMT)
    {
    case S_IFBLK:
        printf("b");
        break;
    case S_IFCHR:
        printf("c");
        break;
    case S_IFDIR:
        printf("d");
        break;
    case S_IFIFO:
        printf("p");
        break;
    case S_IFLNK:
        printf("l");
        break;
    case S_IFREG:
        printf("-");
        break;
    case S_IFSOCK:
        printf("s");
        break;
    default:
        printf("unknown?\n");
        break;
    }

    //判断文件权限
    //个人权限
    if (st.st_mode & S_IRUSR) //r
        printf("r");
    else
        printf("-");

    if (st.st_mode & S_IWUSR) //w
        printf("w");
    else
        printf("-");

    if (st.st_mode & S_IXUSR) //x
        printf("x");
    else
        printf("-");

    //小组成员
    if (st.st_mode & S_IRGRP) //r
        printf("r");
    else
        printf("-");

    if (st.st_mode & S_IWGRP) //w
        printf("w");
    else
        printf("-");

    if (st.st_mode & S_IXGRP) //x
        printf("x");
    else
        printf("-");

    //其他人
    //个人权限
    if (st.st_mode & S_IROTH) //r
        printf("r");
    else
        printf("-");

    if (st.st_mode & S_IWOTH) //w
        printf("w");
    else
        printf("-");

    if (st.st_mode & S_IXOTH) //x
        printf("x");
    else
        printf("-");

    //链接数
    printf(" %ld", st.st_nlink);

    //用户名 需要getpwuid()
    printf(" %s", getpwuid(st.st_uid)->pw_name);

    //组名 需要getgrgid()
    printf(" %s", getgrgid(st.st_gid)->gr_name);

    //文件大小
    printf(" %ld", st.st_size);

    //最后修改的时间
    printf(" %.12s", ctime(&st.st_mtime) + 4);  //+4表示偏移4个地址跳过前4个字符, %.12s表示只打印前12个字符

    //文件名
    printf(" %s\n", argv[1]);

    return 0;
}

stat/fstat/lstat的区别?

stat函数返回一个与此命名文件有关的信息结构

fstat函数获得已在描述符filedes上打开的文件的有关信息,也就是参数是文件描述符,其他与stat相同。

lstat函数类似于stat,但是当命名的文件是一个符号连接时,lstat返回该符号连接的有关信息,而不是由该符号连接引用的文件的信息.

目录操作

围绕目录流进行操作: DIR *

opendir

closedir

readdir

chdir

DIR *opendir(const char *name);
功能:获得目录流
参数:要打开的目录的路径
返回值:成功:目录流
       失败:NULL

struct dirent *readdir(DIR *dirp);
功能:读目录
参数:要读的目录流
返回值:成功:读到的信息    
       失败:NULL
返回值为结构体,该结构体成员为描述该目录下的文件信息

struct dirent {
        ino_t   d_ino;               /* 索引节点号*/
        off_t   d_off;               /*在目录文件中的偏移*/
        unsigned short d_reclen;     /* 文件名长度*/
        unsigned char  d_type;       /* 文件类型 */
        char    d_name[256];         /* 文件名 */
};

int closedir(DIR *dirp);
功能:关闭目录
参数:dirp:目录流


#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main(int argc, char const *argv[])
{
    DIR *dir;
    struct dirent *d;

    dir = opendir(".");
    if (NULL == dir)
    {
        perror("opendir err");
        return -1;
    }

    // d = readdir(dir);
    // printf("%s\n", d->d_name);

    // d = readdir(dir);
    // printf("%s\n", d->d_name);

    //实现ls -a 功能 (打印指定目录所有文件名就可以了)
    while ((d = readdir(dir)) != NULL)
    {
        printf("%s\n", d->d_name);
    }

    return 0;
}

库 Lib

头文件: .h结尾的文件

#include <stdio.h>

<>: 代表去系统路径下查找头文件/usr/include

#include "head.h"

"": 先从当前目录下查找头文件,找不到再去系统路径下查找

头文件以.h结尾,包含: 其他头文件引用,结构体、共用体和枚举的定义,宏定义,重定义,函数的声明,外部引用,条件编译。

源文件: .c结尾的文件

包含main函数的xx.c

包含子函数的xx.c,封装的函数可以在头文件中声明。

库文件(不能包含main函数)

1.1库的定义

当使用别人的函数时除了包含头文件以外还需要有库

头文件:函数声明、结构体等类型定义、头文件、宏定义、其他头文件等

库:把一些常用的函数的目标文件打包在一起,提供相应的函数接口,便于程序员使用。本质上来说库是一种可执行代码的二进制形式文件。

由于windows和linux的本质不同,因此而这库的二进制是不兼容的。(Linux中的C运行库是glibc, 由GUN发布。)

1.2库的分类

静态库和动态库,本质的区别是代码被载入的时刻不同。

2.1 静态库

静态库在程序编译时会被复制到目标代码中,.a结尾

优点:程序运行时将不再需要该静态库,运行时无需加载库,运行速度更快,可移植性好

缺点:静态库中的代码复制到了程序中,因此体积较大;静态库升级后,程序需要重新编译链接。

2.2 动态库

动态库是在程序运行时才被载入代码中。也叫共享库,以.so结尾。

优点:程序在执行时加载动态库,代码体积小;程序升级更简单;

不同应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。

缺点:运行速度慢,运行时还需要动态库的存在,移植性较差。

2.2.1静态库的制作

  1. 将源文件编译生成目标文件

gcc -c fun.c -o fun.o

  1. 创建静态库用ar命令,将多个.o生成.a

ar crs libfun.a fun.o

注意:静态库文件名的命名规范是以lib为前缀,紧接着跟静态库名,扩展名为.a

  1. 测试使用静态库

gcc main.c -L. -lfun

注意:-L指定静态库的路径, -l指定库名

执行: ./a.out

2.2.2动态库的制作

  1. 用gcc来创建共享库

gcc -fPIC -c fun.c -o fun.o //-fPIC创建与地址无关的编译程序

gcc -shared fun.o -o libmyfun.so //生成动态库

  1. 测试使用动态库

sudo cp libmyfun.so /lib

gcc main.c -lmyfun

./a.out : 可以正常编译通过,但是运行报错./a.out: error while loading shared libraries: libmyfun.so: cannot open shared object file: No such file or directory

原因:当加载动态库时,系统会默认从/lib或/usr/lib路径下查找库文件,所以不用-L加路径了直接gcc main.c  -lmyfun就可以了

解决方法(有三种):

  1. 把库拷贝到/usr/lib和/lib目录下。(此方法编译时不需要指定库的路径)
  2. 在LD_LIBRARY_PATH环境变量中加上库所在路径。

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

(终端关闭,环境变量就没在了)

  1. 添加/etc/ld.so.conf.d/*.conf文件。把库所在的路径加到文件末尾,并执行ldconfig刷新

sudo vi xx.conf

添加动态库存在的路径,如:

/home/hq/work/lib

2.2.3静态库和动态库总结

静态库:编译阶段,体积大,移植性好,升级麻烦,以.a结尾。

动态库: 运行阶段加载代码,体积小,移植性差,升级简单,以.so结尾。

可以看出静态库编译出来的程序体积大一些:

升级演示:改变制作成库的源文件,然后重新制作库文件

动态库只需要重新生成动态库,不需要重新编译连接库了

静态库升级需要重新编译:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2082641.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

最新黑名单查询录入系统_全开源源码

最新黑名单查询录入系统_全开源源码 前端html 后端layui 操作部分都采用API接口的方式实线 集结了layui表格的多数据操作&#xff0c;添加&#xff0c;批量删除&#xff0c;分页&#xff0c;单项删除 后台数据修改采用绑定参数的形式来进行修改可以很好的预防数据库注入…

【Python入门】第3节 循环语句

&#x1f4d6;第3节 循环语句 ✅while循环的基础语法✅while循环的嵌套✅while循环的嵌套案例✅for循环的基础语法&#x1f9ca;基础语法&#x1f9ca;range语句&#x1f9ca;变量作用域 ✅for循环的嵌套应用✅循环中断 : break和continue ✅while循环的基础语法 只要条件满足…

Thread的属性和方法及如何中断一个线程

文章目录 一. Thread提供的属性和方法1. Thread常见的构造方法2. 属性及获取方法 二. 中断(终止)一个线程1) 自己来实现控制线程结束的例子2) 使用Thread提供的interrupt和isInterrupted方法来实现控制线程结束 一. Thread提供的属性和方法 1. Thread常见的构造方法 ③ 在创建…

戏曲多多 v1.0.4 — 专为老年人打造的戏曲娱乐软件(含经典评书与广场舞)

戏曲多多 TV 是一款专为老年人量身打造的视频娱乐软件&#xff0c;安装在智能电视、智能机顶盒、投影仪等安卓系统设备上后&#xff0c;老年人可以在电视上轻松观看各种戏曲视频。软件涵盖豫剧、京剧、秦腔、越剧、昆曲、淮剧、川剧、黄梅戏等多种戏曲类型。除了戏曲&#xff0…

Java设计模式之原型模式详细讲解和案例示范

引言 在软件设计中&#xff0c;设计模式为我们提供了可复用的解决方案&#xff0c;以应对常见的设计问题。原型模式&#xff08;Prototype Pattern&#xff09;是创建型设计模式的一种&#xff0c;它允许通过复制现有对象来创建新对象&#xff0c;而不需要了解创建过程的细节。…

【软件】常用软件教程一:码云(Gitee)使用方法

文章目录 一、简介二、创建远程仓库三、配置SSH公钥四、同步 Gitee 仓库内容到本地五、本地新建文件并同步至 Gitee六、删除远程仓库中的指定文件七、常见代码 一、简介 Git 是一种分布式版本控制系统&#xff0c;用于跟踪和管理代码的变更。它是由 Linus Torvalds 创建的&…

ctfhub-web-SSRF(内网访问-上传文件)

www.ctfhub.com less-1 内网访问 步骤一&#xff1a;开启环境&#xff0c;查看提示 步骤二&#xff1a;输入urlhttp://127.0.0.1/flag.php 得出结果 显示提交成功 less-2 伪协议读取文件 步骤一&#xff1a;开启环境&#xff0c;查看提示 步骤二&#xff1a;输入urlfile://…

英伟达财报引爆AI投资狂潮?华尔街众说纷纭

英伟达&#xff0c;这个名字最近可是火爆了整个科技圈。作为全球最大的GPU供应商&#xff0c;英伟达的每一次动作都牵动着无数投资者的神经。尤其是即将到来的财报发布&#xff0c;更是让市场充满了期待和忐忑。 华尔街聚焦&#xff1a;AI巨头能否持续高增长&#xff1f; 整个…

背完这些软件测试核心面试题,offer轻松拿捏了!

你赞同过 软件测试和开发 相关内容 01、您所熟悉的测试用例设计方法都有哪些&#xff1f;请分别以具体的例子来说明这些方法在测试用例设计工作中的应用。 答&#xff1a;有黑盒和白盒两种测试种类&#xff0c;黑盒有等价类划分法&#xff0c;边界分析法&#xff0c;因果图法…

NVDA财报公布在即,港股围观情绪明显

港股上午盘三大指数低开低走&#xff0c;恒生科技指数一度大跌1.59%&#xff0c;恒指再度失守17800点。盘面上&#xff0c;大型科技股全线下跌令大市承压&#xff0c;百度跌超3%&#xff0c;网易、美团跌超2%&#xff0c;腾讯、快手、阿里巴巴跌超1%&#xff1b;多家房企宣布营…

Git学习(001 git介绍以及安装)

尚硅谷2024最新Git企业实战教程&#xff0c;全方位学习git与gitlab 总时长 5:42:00 共40P 此文章包含第1p-第p4的内容 文章目录 介绍Git介绍GitLab介绍 概述Git安装版本控制工具介绍 介绍 Git介绍 GitLab介绍 相当于中央仓库 概述 Git安装 进入官网(下载当前版本 2.43.0) …

JavaScript ES6+ 新特性

JavaScript ES6 新特性 引言 随着前端技术的不断发展&#xff0c;JavaScript 语言也在不断演进。自 ES6&#xff08;ES2015&#xff09;发布以来&#xff0c;JavaScript 引入了许多新的特性和语法&#xff0c;极大地提升了开发者的编程体验和代码的可维护性。本篇文章将详细探…

测试必备--轻松掌握弱网测试技巧

在如今的移动互联网时代,用户对应用的依赖性越来越强。然而,网络环境并非总是理想的,特别是在信号较弱或网络不稳定的情况下,应用的表现尤为重要。你是否曾遇到过这样的情况:在地铁、地下停车场或者偏远地区,网络信号减弱,应用频繁卡顿甚至崩溃?为了确保用户在弱网环境…

JS WebSocket 深度解析

JS WebSocket 深度解析 文章目录 JavaScript WebSocket 深度解析一、WebSocket 是什么二、JS 中如何使用 WebSocket1. 创建 WebSocket 对象2. 连接打开事件3. 监听消息事件4. 监听错误事件5. 关闭连接 三、WebSocket 包含哪些属性或方法 API1. 属性2. 方法 四、扩展与高级技巧1…

微分方程(Blanchard Differential Equations 4th)中文版Section4.5

塔科马海峡大桥 1940年7月1日,耗资600万美元的塔科马海峡大桥正式通车。仅仅四个月后的11月7日,在一场风暴中,这座桥解体并倒塌。这座悬索桥全长超过一英里,曾在它短暂的使用期内因桥面在风中剧烈摆动而被称为“跳跃的格蒂”(Galloping Gertie)。大桥的倒塌不仅成为一场…

KAN+Transformer,一个快速发论文的新创新点!

KAN爆火至今&#xff0c;关于它和Transformer谁更强的问题还没定论&#xff0c;这俩结合的工作效果却愈发出众了&#xff0c;短时间内就有了不少高质量论文发表。 不得不说&#xff0c;这是一种富有创新性的尝试&#xff0c;利用了KAN的灵活性和可解释性&#xff0c;以及Trans…

ocr识别遇到的问题(nested exception is java.lang.UnsatisfiedLinkError)

目录 前言&#xff1a; 问题描述&#xff1a; 解决思路&#xff1a; 解决方法&#xff1a; 总结反思&#xff1a; 前言&#xff1a; 上篇讲过我使用冰蓝的jar包在Java 项目中扫描识别图片中的文字&#xff0c;这篇写更新上线中遇到的问题。 问题描述&#xff1a; 项目打…

c++习题26-大整数加法

目录 一&#xff0c;题目 二&#xff0c;思路 三&#xff0c;代码 一&#xff0c;题目 描述 求两个不超过200位的非负整数的和。 输入 有两行&#xff0c;每行是一个不超过200位的非负整数&#xff0c;可能有多余的前导0。 输出 一行&#xff0c;即相加后的结果。结果里不…

论文合作容易踩坑?学术大咖为你揭秘合作研究中的潜规则

我是娜姐 迪娜学姐 &#xff0c;一个SCI医学期刊编辑&#xff0c;探索用AI工具提效论文写作和发表。 知乎上的话题&#xff0c;引发大家热议。因为如今合作发表论文在学术圈越来越普遍了。 随着低垂果实都发表了&#xff0c;大家在自己的领域越做越细分&#xff0c;再加上人工智…

WiFi标签注册(电脑版)

安装WiFi-Tool工具 需要windows系统电脑并且有WiFi功能 下载软件安装包&#xff1a;http://a.picksmart.cn:8088/picksmart/app/WiFi-Tool-Setup-V1.0.37.zip 配置操作流程 登录WiFi标签管理系统到设备管理-产品管理&#xff0c;复制“产品ApiKey”参数&#xff0c;打开“WiFi-…