Linux高级编程——文件系统管理

文件系统管理

​ 如果说将文件系统看成树形结构,那么文件夹就是分支节点,文件就是叶子节点。

Linux系统调用(System Call):就是 Linux 系统提供的一堆函数,只能用于 Linux 系统/Unix系统。

操作系统源码:https://www.kernel.org/

文件 I/O 相关函数:

  • open:打开文件,如果成功就返回一个文件描述符(File Descriptor,就是一个非负整数,范围为:0 ~65535)
  • close:关闭文件
  • read
  • write
  • lseek:文件指针位置,可通过lseek改文件指针也可获取当前文件指针的位置
open函数

open函数参数详解:

const char *pathname,int flags,mode_t mode);

fp = open(参数1,参数2,参数3);

参数1:代表文件路径及文件名

参数2:表示打开方式,根据man手册,flags有三个固定参数(宏):O_RDONLY 只读 、 O_WRONLY 只写 、 O_RDWR 可读可写。(没有文件不会自动创建)

另外还可以带上附加参数:

O_CREAT:若打开一个空文件,则会自动创建一个。

O_EXCL:配合O_CREAT使用,文件存在,则返回错误消息

O_APPEND:以追加方式打开,类似与C库中的fopen()函数参数a

O_NOCTTY:意为阻止文件作为打开控制终端。

O_TRUNC:文件存在,则清空文件;

参数3:mode,设置文件的权限 是八进制的权限码,但是起不到决定性的效果,最终权限为mode与~umask 按位与后得到的值(后续详解umask命令)。

三个特殊的文件描述符(fp):

  • 0:标准输入文件
  • 1:标准输出文件
  • 2:标准错误文件(查找stdio.h文件 find / -name stdio.h 2>/dev/null 标准错误信息重定向到了null中 )

可变参数函数

int sum(int a, int b, int c)  //函数参数是入栈存储,c地址最小,a地址最大,&a=&b+1=&c+2
{
	printf("");
}

疑惑?(下例为何实现不了?)
/*
可变长参数函数声明
    求任意个数的整数和
    int sum(int n, ...);  //此时n地址最大
通过第一个参数来推出后面的参数个数,此时n为后面参数个数
int sum(int n, ...)
{
    int s = 0;
    int i;
    
    for(i = 0;i < n; i++)
    {
        s += *(&n - i - 1);
    }
    return s;
}
*/

//通过测试64位系统下:
//第一个参数为参数数量,以第一个参数为首地址,第二个参数距第一个参数28个字节,后续 + 8 个字节;
//按照这个逻辑首元素地址最低,且在栈顶,故栈低元素地址最高
int sum(int n, ...)
{
    int s = 0;
    int i;
    
    for(i = 0;i < n; i++)
    {
        s += *(&n + 7 + i * 2);
    }
    return s;
}    
    
//传统做法:
#include <stdarg.h>
int sum(int n, ...)
{
    va_list vl;
    va_start(vl, n);
    int i;
    int s = 0;
    for(i = 0;i < n; i++)
    {
        s +=va_arg(vl, int);
    }
    va_end(vl);
}

umask命令

umask:设置新建文件的权限掩码,返回值为原来的掩码,默认掩码为002(Ubuntu 20.04)

在终端直接输入umask可以得到系统默认的文件权限掩码。

在open函数设置第三个参数时设置的mode & ~掩码 得到文件权限

例如:

mode = 0777 则 0777 & 775,则文件权限为:rwxrwxr-x

mode = 0123 则 0123 & 775,则文件权限为:–x-w—x

当然也可以自定义umask的值,但是只对当前进程有效

当设置umask(0);则默认掩码为 002。

则mode = 0777 则 0777 & 775,则文件权限为:rwxrwxrwx,满权限

cp命令实现
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char** argv)
{
    int fd1,fd2;
    int ret;  //返回值
    char buf[1024];//容器
    fd1 = open(argv[1], O_RDONLY);
    if(fd1 == -1)
    {
        perror("open fail");
        return 1;
    }
    fd2 = open(argv[2],O_WRONLY | O_CREAT,0777);
    if(fd2 == -1)
    {
        perror("open fail");
        return 1;
    }
    while((ret = read(fd1, buf, sizeof(buf))) > 0)
    {
        write(fd2,buf,ret);//此时可判断write函数的返回值。
    }
    close(fd1);
    close(fd2);
    return 0;
}

Linux系统函数实现是无缓冲的读写操作,而标准C库函数中的文件 I/O 函数实现的是有缓冲的读写操作,其后者就是调用前者实现的,只不过增加了缓冲处理。

修改文件的属性信息函数:

  • chmod:更改文件的权限
  • chown:更改文件的所有者或组(通过用户id和组群id来改——getpwnam()通过用户名找用户信息)
  • utime:修改文件的最近访问时间和最近修改时间
  • truncate:裁剪文件
  • rename:修改文件名

删除文件:remove(可删文件和非空文件夹),unlink(删文件),rmdir(删空文件夹)

创建文件夹:mkdir

创建链接文件:link (与ln命令对应)

硬链接的创建:ln oldfile newfile——link()函数

软链接的创建:ln -s old.dir soft.link.dir(带上-s即可)——symlink()函数

获取文件的属性信息:stat (与ls -la对应)

读取文件夹相关函数:opendir,readdir,closedir

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值