Linux文件操作[提升函数]

简介: Linux文件操作[提升函数]

@[toc]

前言

上一篇文章介绍了一下关于在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:bad address

下面就会有一道题,就是使用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;
}

运行后的结果如下:

rw

二、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的权限为:

-rw-rw-r--

执行上面代码后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;
}

编译后并执行会发现这个程序并没有执行成功,并输出了下面的语句:

chown: Operation not permitted

原因是因为当前用户的权限并不高,如果要执行得需要更高的权限,所以这里需要切换至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

总结

这些函数都是比较简单的,大家多练习就可以熟练掌握。
这个网站是我搬运我CSDNsha上的,其实是为了拿个礼品所以搬运的,大家可以看看CSDN上的:https://blog.csdn.net/zagzag001/article/details/130501131

相关实践学习
CentOS 7迁移Anolis OS 7
龙蜥操作系统Anolis OS的体验。Anolis OS 7生态上和依赖管理上保持跟CentOS 7.x兼容,一键式迁移脚本centos2anolis.py。本文为您介绍如何通过AOMS迁移工具实现CentOS 7.x到Anolis OS 7的迁移。
目录
相关文章
|
2月前
|
人工智能 监控 Shell
常用的 55 个 Linux Shell 脚本(包括基础案例、文件操作、实用工具、图形化、sed、gawk)
这篇文章提供了55个常用的Linux Shell脚本实例,涵盖基础案例、文件操作、实用工具、图形化界面及sed、gawk的使用。
558 2
|
2月前
|
Linux Shell
Linux系统编程:掌握popen函数的使用
记得在使用完 `popen`打开的流后,总是使用 `pclose`来正确关闭它,并回收资源。这种做法符合良好的编程习惯,有助于保持程序的健壮性和稳定性。
113 6
|
2月前
|
Linux Shell
Linux系统编程:掌握popen函数的使用
记得在使用完 `popen`打开的流后,总是使用 `pclose`来正确关闭它,并回收资源。这种做法符合良好的编程习惯,有助于保持程序的健壮性和稳定性。
144 3
|
2月前
|
Linux
在Linux内核中根据函数指针输出函数名称
在Linux内核中根据函数指针输出函数名称
|
3月前
|
Linux PHP
Linux CentOS 宝塔 Suhosin禁用php5.6版本eval函数详细图文教程
【8月更文挑战第27天】本文介绍两种禁用PHP执行的方法:使用`PHP_diseval_extension`禁用和通过`suhosin`禁用。由于`suhosin`不支持PHP8,仅适用于PHP7及以下版本,若服务器安装了PHP5.6,则需对应安装`suhosin-0.9.38`版本。文章提供了详细的安装步骤,并强调了宝塔环境下与普通环境下的PHP路径差异。安装完成后,在`php.ini`中添加`suhosin.so`扩展并设置`executor.disable_eval = on`以禁用执行功能。最后通过测试代码验证是否成功禁用,并重启`php-fpm`服务生效。
49 2
|
3月前
|
Shell Linux C语言
Linux0.11 execve函数(六)
Linux0.11 execve函数(六)
69 1
|
3月前
|
Linux API
Linux源码阅读笔记07-进程管理4大常用API函数
Linux源码阅读笔记07-进程管理4大常用API函数
|
3月前
|
Linux 数据安全/隐私保护 Perl
解锁Linux高手秘籍:文件操作+命令解析大揭秘,面试场上让你光芒万丈,技术实力惊艳四座!
【8月更文挑战第5天】Linux作为服务器与嵌入式系统的基石,其文件管理和命令行操作是技术人员必备技能。本文从文件操作和基础命令两大方面,深入浅出地解析Linux核心要义,助你在面试中脱颖而出。首先探索文件系统的树状结构及操作,包括使用`ls -la`浏览文件详情、`touch`创建文件、`rm -r`慎删目录、`cp`与`mv`复制移动文件、以及利用`find`搜索文件。接着掌握命令行技巧,如用`cat`、`more`和`less`查看文件内容;借助`grep`、`sed`与`awk`处理文本;运用`ps`、`top`和`kill`管理进程;并通过`chmod`和`chown`管理文件权限。
79 8
|
3月前
|
安全 Unix Linux
Linux Clone函数
Linux Clone函数
64 3
|
3月前
|
Linux
Linux0.11 文件打开open函数(五)
Linux0.11 文件打开open函数(五)
48 0
下一篇
无影云桌面