IO进程—库、获取文件属性

目录

库的定义

库的分类

静态库的制作

 动态库的制作

动态库和静态库的区别

静态库

动态库

文件属性获取

获取文件属性

stat

获取用户属性

getpwuid

获取组属性

getgrgid

将时间转化为字符串

ctime


库的定义

通俗来讲就是将用户写好的程序打包成一个整体,当其他模块或用户使用时,只需要有这个库文件就可以了,不需要源代码文件。也可以理解为一组预先编译好的方法的集合。本质上来说,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行

库:

头文件 #include“”       #include <>        其他头文件

结构体        宏定义        函数声明        共用体         枚举        条件编译        重定义

例如:源文件 main.c

库的分类

静态库的制作

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

        gcc -c xxx.c -o xxx.o

2. 创建静态库,用ar命令,将多个 .o文件准化成 .a文件

        ar crs libxxx.a xxx.o

3. 测试静态库的使用

        gcc main.c -L库的路径 -l库名

4. 执行 ./a.out

 动态库的制作

1. 编译生成目标文件

        gcc -fPIC -c xxx.c -o xxx.o

2.创建共享库

        gcc shared -o libxxx.so xxx.o

3. 测试动态库的使用

        gcc main.c -L库的路径 -l库名

4. 执行 ./a.out

以上步骤可以编译通过,但是运行时会报错 

错误展示: 

原因:

动态库是在实际运行时载入,当加载动态库时,系统会默认从 /lib或 /usr/lib 路径下查找库文件

解决方法:

1. 把库文件拷贝到 /usr/lib 和 /lib 目录下(此方法适用于编译时不需要指定库的路径)

2. 在 LD_LIBRARY_PATH 环境变量中加上库所在的路径。

        export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

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

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

        sudo vi /etc/ld.so.conf.d/*.conf

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

        /home/hq/teach/23043/IO/day3/share

添加成功后用 wq!保存退出,之后刷新:sudo ldconfig

动态库和静态库的区别

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

静态库

静态库在程序编译时会被连接到目标代码中。

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

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

动态库

动态库在程序运行时才被载入到代码中。

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

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

文件属性获取

获取文件属性

stat

格式:int stat(const char *path, struct stat *buf);
功能:获取文件属性
参数:
    path:文件路径名
    buf:保存文件属性信息的结构体
返回值:
    成功:0
    失败:-1
struct stat {
        dev_t     st_dev;         /* 设备包含文件ID */
        ino_t     st_ino;         /* inode号 */
        mode_t    st_mode;        /* 文件类型和权限 */
        nlink_t   st_nlink;       /* 硬链接数 */
        uid_t     st_uid;         /* 用户ID */
        gid_t     st_gid;         /* 组ID */
        off_t     st_size;        /* 大小 */
        dev_t     st_rdev;        /* 设备ID */
        time_t    st_atime;       /* 最后访问时间 */
        time_t    st_mtime;       /* 最后修改时间 */
        time_t    st_ctime;       /* 最后状态改变时间 */
    };

获取用户属性

getpwuid

格式:struct passwd *getpwuid(uid_t uid);
功能:通过用户 id 获取用户属性
参数:uid:用户 id
返回值:
    返回保存用户相关属性结构体的地址
    失败:NULL
struct passwd {
               char   *pw_name;       /* 用户名 */
               char   *pw_passwd;     /* 密码 */
               uid_t   pw_uid;        /* user ID */
               gid_t   pw_gid;        /* group ID */
               char   *pw_gecos;      /* 真实名 */
               char   *pw_dir;        /* 主目录 */
               char   *pw_shell;      /* 使用的shell */
};

获取组属性

getgrgid

格式:struct group *getgrgid(gid_t gid);
功能:通过组 id 获取组属性
参数:gid:组 id
返回值:返回保存组相关属性结构体的地址 err:NULL
  struct group {
               char   *gr_name;        /* 组名 */
               char   *gr_passwd;      /* 组密码 */
               gid_t   gr_gid;         /* 组ID */
               char  **gr_mem;         /*组成员账号 */
};

将时间转化为字符串

ctime

 格式:char *ctime(const time_t *timep);
 功能:将时间秒数转化为字符串表示
 参数:timep :时间
 返回值:成功返回字符串首地址
 失败:NULL
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <time.h>

int main(int argc, char const *argv[])
{
    struct stat buf;
    if (stat("./1ls.c", &buf) < 0)
    {
        perror("stat err");
        return -1;
    }
    printf("inod:%lu nlink:%d\n",
           buf.st_ino, buf.st_nlink);
    printf("mode:%#o\n", buf.st_mode);
    //获取文件类型
    if ((buf.st_mode & S_IFMT) == S_IFREG)
        printf("-\n");
    if ((buf.st_mode & S_IFMT) == S_IFDIR)
        printf("d\n");
    if (S_ISREG(buf.st_mode))
        putchar('-');
    //获取文件权限
    if (buf.st_mode & S_IRUSR)
        printf("r");
    else
        printf("-");
    //获取用户名
    printf(" %s ", getpwuid(buf.st_uid)->pw_name);
    //获取时间
    printf("%.12s ", ctime(&buf.st_mtime)+4);
    putchar(10);

    return 0;
}

练习1:

用stat完成 ls -l 文件名 功能

文件权限:

        首先和4位与操作看是否有r权限,再和2位与看是否有w权限,再和1位与看是否有x权限

        通过位移操作和每一个权限相与看是否有权限

        0400:十进制数,每一组权限都有rwx三种,最高位权限有的话,其二进制数为100,位与后再右移一位。

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

int main(int argc, const char *argv[])
{
    struct stat buf;
    if (stat(argv[1], &buf) < 0)
    {
        perror("error \n");
        return -1;
    }
    //判断文件类型
    if (S_ISREG(buf.st_mode))
        printf("-");
    else if (S_ISDIR(buf.st_mode))
        printf("d");
    else if (S_ISSOCK(buf.st_mode))
        printf("s");
    else if (S_ISBLK(buf.st_mode))
        printf("b");
    else if (S_ISFIFO(buf.st_mode))
        printf("p");
    else if (S_ISLNK(buf.st_mode))
        printf("l");
    else if (S_ISCHR(buf.st_mode))
        printf("c");
    /*   
    //user
    if (buf.st_mode & S_IRUSR)
        printf("r");
    else
        printf("-");
    if (buf.st_mode & S_IWUSR)
        printf("w");
    else
        printf("-");
    if (buf.st_mode & S_IXUSR)
        printf("x");
    else
        printf("-");
    //group
    if (buf.st_mode & S_IRGRP)
        printf("r");
    else
        printf("-");
    if (buf.st_mode & S_IWGRP)
        printf("w");
    else
        printf("-");
    if (buf.st_mode & S_IXGRP)
        printf("x");
    else
        printf("-");
    //other
    if (buf.st_mode & S_IROTH)
        printf("r");
    else
        printf("-");
    if (buf.st_mode & S_IWOTH)
        printf("w");
    else
        printf("-");
    if (buf.st_mode & S_IXOTH)
        printf("x");
    else
        printf("-");
    */
    //获取文件权限
    char arr[3] = "rwx";
    for (int i = 0; i < 9; i++)
        (buf.st_mode & (0400 >> i)) ? printf("%c", arr[i % 3]) : printf("-");
    //硬链接个数
    printf(" %d", buf.st_nlink);
    //uid:hq
    printf(" %s", getpwuid(buf.st_uid)->pw_name);
    //gid:hq
    printf(" %s", getgrgid(buf.st_gid)->gr_name);
    //文件大小
    printf(" %ld", buf.st_size);
    //最后更新时间
    printf(" %.12s", 4 + ctime(&buf.st_mtime)); //4+:跳过前四位,.12位宽12右对齐
                                                //文件名
    printf(" %s", argv[1]);

    putchar('\n');

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值