Linux文件操作[提升函数]

前言

上一篇文章介绍了一下关于在Linux中对于文件操作的简单函数,但是只学习了简单函数对文件的一些复杂操作是不太行的,所以这篇文章给大家介绍一下对文件操作的一些复杂函数。

一、stat函数

stat函数是可以获取文件的一些信息的,这些信息存放在一个结构体中,通过调用这个函数获取文件的信息,然后通过返回的结构体将文件的信息读取出来。
函数的原型如下:

#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 *statbuf)
int lstat(const char* pathname, struct stat* buf);
功能:
    获取文件状态信息
    stat和lstat的区别:
    	当文件是一个符号链接时,lstat返回的是该符号链接本身的信息;
    	而stat返回的是该链接指向的文件的信息。
参数:
    path:文件名
    buf:保存文件信息的结构体
返回值:
    成功:0
    失败:-1

而这个结构体struct stat中的结构如下:

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 */
    dev_t     st_rdev;        /* 设备ID(如果特殊文件) */
    off_t     st_size;        /* 总大小,以字节为单位 */
    blksize_t st_blksize;     /* 文件系统I/O的块大小 */
    blkcnt_t  st_blocks;      /* 已分配512B块的数量 */

    /* 从Linux 2.6开始,内核支持纳秒
		以下时间戳字段的精度。
		Linux 2.6之前版本的详细信息请参见“说明”。 */

    struct timespec st_atim;  /* 最后一次访问时间 */
    struct timespec st_mtim;  /* 最后一次修改时间 */
    struct timespec st_ctim;  /* 最后一次状态更改的时间 */

    #define st_atime st_atim.tv_sec      /* 向后兼容性 */
   #define st_mtime st_mtim.tv_sec
   #define st_ctime st_ctim.tv_sec
};

比如说查看一个文件的信息,代码如下:

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

int main(){
        struct stat ps;
        int ret;
        ret = stat("demo1.c", &ps);
        if (ret == -1){
                perror("stat");
                return -1;
        }
        printf("%ld", ps.st_dev);
        return 0;
}

上面的代码是查看了一下设备的ID,需要注意的是,在创建结构体的时候不能使用指针的形式,也就是创建struct stat*,这样子是不可以的,如果使用了会出现下面的错误:
在这里插入图片描述
下面就会有一道题,就是使用stat获取文件的用户权限,代码如下:

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

int main(){
        int ret;
        struct stat ps;
        ret = stat("demo1.c", &ps);
        if (ret == -1){
                perror("stat");
                return -1;
        }
        if (ps.st_mode & 0400){
                printf("r");
        }
        else{
                printf("-");
        }
        if (ps.st_mode & 0200){
                printf("w");
        }
        else{
                printf("-");
        }
        if (ps.st_mode & 0100){
                printf("x");
        }
        else{
                printf("-");
        }
        printf("\n");
        return 0;
}

运行后的结果如下:
在这里插入图片描述

二、access函数

这个函数是来判断文件是否有某种权限的,函数的原型如下:

#include <unistd.h>
int access(const char* pathname, int mode);
功能:测试指定文件是否具有某种属性
参数:
    pathname:文件名
    mode:文件权限,4种权限
        R_OK:	是否有读写权限
        W_OK:	是否有写权限
        X_OK:	是否有执行权限
        F_OK:	测试文件是否存在
返回值:
	0:有某种权限,或文件存在
    -1:没有,或文件不存在

这个函数相当于来说比较简单,比如说判断一下demo1.c这个文件中是否存在读写权限,那么代码如下:

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

int main(){
        int ret;
        ret = access("demo1.c", R_OK);
        if (ret == -1){
                perror("access");
                return -1;
        }
        else if(ret == 0){
                printf("文件有读的权限\n");
        }
        return 0;
}

三、chmod函数

chmod是Linux中的一个指令,是用来修改一个文件的权限的指令,而这里讲的chmod函数也是
来修改文件的权限的,只不过需要我们像调用函数一样调用它。
chmod函数的原型如下:

#include <sys/stat.h>
int chmod(const char* pathname, mode_t mode);
功能:修改文件权限
参数:
    filename:文件名
    mode:权限(8进制数)
返回值:
    成功:0
    失败:-1

例如下面的代码:

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

int main(){
        int ret;
        ret = chmod("text", 0000);
        if (ret == -1){
                perror("chmod");
                return -1;
        }
        return 0;
}

将text文件的权限修改为0000,之前text的权限为:
在这里插入图片描述
执行上面代码后text文件的权限为:
在这里插入图片描述
可以发现权限是已经进行了修改。

四、chown函数

这个函数是修改文件所属组和角色的函数,和命令的用法一样,函数的原型如下:

#include <unistd.h>
int chown(const char* pathname, uid_t owner, git_t group);
功能:
    修改文件所有者和所属组
参数:
    pathname:文件或目录名
    owner:文件所有者id,通过查看 /etc/passwd 得到所有者id
    group:文件所属组id,通过 /etc/group 得到用户组id
返回值:
    成功:0
    失败:-1

需要注意一下,这里的ownergroup得填写用户和组的id,需要去到/etc/passwdetc/group文件中去查看,在命令行中输入下面的命令即可查看其中的内容:

cat /etc/passwd
cat /etc/group

在这里插入图片描述
可以看到,用户root的id为0,那如果要修改的话就可以在owner这填写0,组也是同样的操作。
如果不想动这个文件的所属组或者所属用户,那可以直接填写-1,这样就可以不修改了。
下面的代码是修改text文件的所属用户:

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

int main(){
        int ret;
        ret = chown("text", 1004, -1);
        if (ret == -1){
                perror("chown");
                return -1;
        }
        return 0;
}

编译后并执行会发现这个程序并没有执行成功,并输出了下面的语句:
在这里插入图片描述
原因是因为当前用户的权限并不高,如果要执行得需要更高的权限,所以这里需要切换至root用户再来进行执行,这样就能成功的执行了。

五、truncate函数

这个函数是可以修改文件的大小的函数,函数原型如下:

#include <unistd.h>
#include <sys/types.h>
int truncate(const char* path, off_t length);
功能:修改文件大小
参数:
    path:文件名字
    length:指定的文件大小
    	a)比用来小,删除后边的部分
    	b)比原来大,向后拓展
返回值:
    成功:0
    失败:-1

比如说我创建了一个文件叫做text1,这个文件中只有一下的内容:
在这里插入图片描述
长度为:4,现在我写好了一个程序,程序主要是修改这个文件的大小为100,代码如下:

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

int main(){
        int ret;
        ret = truncate("text1", 100);
        if (ret == -1){
                perror("truncate");
                return -1;
        }
        return 0;
}

执行完这个程序后,查看这个文件的大小,会发现它变成了:100
在这里插入图片描述
文件中的内容也增加了一些:
在这里插入图片描述
会发现这后面增加的内容看不明白,那这些是什么呢?其实这些就是空洞,后面对文件操作或者是内存操作文件会经常见到,这出现的原因主要是因为你本来写的东西只有4个(3个字符1个\0),而现在要求扩大这个文件,所以就需要一些占位的内容,所以这些占位的内容就是使用空洞来进行占位。
我再修改一下这个文件,将它的大小变为100
在这里插入图片描述
然后我将这个文件的大小修改为10,看看这个文件会发生什么。

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

int main(){
        int ret;
        ret = truncate("text1", 10);
        if (ret == -1){
                perror("truncate");
                return -1;
        }
        return 0;
}

在这里插入图片描述
在这里插入图片描述
可以看到多出来的内容就全部被截断了,只留下长度为10的内容。

六、rename函数

这个函数是将文件进行改名的函数,函数原型如下:

#include <stdio.h>
int rename(const char* oldpath, const char* newpath);
功能:把oldpath的文件名改成newpath
参数:
  	oldpath:旧文件名
    newpath:新文件名
返回值:
    成功:0
    失败:-1

总结

这些函数都是比较简单的,大家多练习就可以熟练掌握。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恰柠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值