【Linux 基础 IO】文件系统,对系统调用函数的讲解

1.初步理解文件

🐧① 打开文件: 本质是进程打开文件,只有程序运行起来文件才被打开;

🐧②文件没有被打开的时候在哪里呢? ----- 在磁盘中

🐧③进程可以打开很多个文件吗? ---- 可以的🙆‍

🐧④系统中可不可以存在很多个进程呢? ---- 可以存在

🐧⑤由第3、4点可以得知,在OS内部一定存在大量的被打开的文件(如何管理呢? 先描述,在组织


2.C语言环境下的文件操作

2.1 C库中 fopen、fwrite 的讲解

🐧①语法:
在这里插入图片描述


🐧②fopen () 的打开方式:

Ⅰ.✌ 以w 的方式打开: 如果该路径下没有该文件的话,则创建该文件,如果该文件存在的话,则在打开文件的时候,把文件的内容清空;

Ⅱ.✌a的方式打开: 直接在该文件的后面追加内容,不会清空文件;

  • 以下两个知识点是 Linux 中的概念:

Ⅲ.✌输出重定向>,实际上就是充当 w的作用;
在这里插入图片描述

Ⅳ.✌追加重定向>>,它实际充当的是 a的作用;
在这里插入图片描述



🐧② fprintf ( ) 的使用

在这里插入图片描述

将内容打印到 log.txt 这个文件中:
在这里插入图片描述


2.2 C文件操作的实例
  • 三点要求如下所示: 🔍

🐧Ⅰ. 对fopen, fread, fwrite, fseek, fclose等函数的使用;

🐧Ⅱ.使用代码打开当前路径下的“bite”文件(如果文件不存在在创建文件),向文件当中写入“linux so easy!”.

🐧Ⅲ.在从文件当中读出文件当中的内容, 打印到标准输出当中; 关闭文件流指针;

  • 代码实现如下:
    🐧代码涉及的知识点如下
    🍎Ⅰ. fopen () 函数的打开方式:
    在这里插入图片描述

🍎Ⅱ. fseek( ) 函数的讲解
大家说说 fseek( ) 函数有什么大的用处呢?

我们在向一个文件写入数据的时候,当我们写完以后,文件的读写位置就停在了写完之后的位置,当我们再对该文件进行读取的时候,读入的都是该文件有效内容之后的数据,导致我们无法读到我们想要的内容,而 fseek( ) 函数就可以把文件的读写位置移动到文件的开头,我们就可以读到想要的内容啦! 😃

int fseek(FILE *stream, long offset, int whence);    

offset (偏移量) : 以字节为单位;

whence(何处) :用于定义参数 offset 偏移量对应的参考值(可以理解为文件读写位置的初始值),该参数为下列其中一种(宏定义):
SEEK_SET :读写偏移量将指向 offset 字节位置处(从文件头部开始算);

SEEK_CUR :读写偏移量将指向当前位置偏移量 + offset 字节位置处, offset 可以为正、也可以为负,如果是正数表示往后偏移,如果是负数则表示往前偏移;

SEEK_END :读写偏移量将指向文件末尾 + offset 字节位置处,同样 offset 可以为正、也可以为负, 如果是正数表示往后偏移、如果是负数则表示往前偏移。



🍎Ⅲ.fread ( ) 函数

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

在这里插入图片描述


🍎Ⅲ.fwrite ( ) 函数

在这里插入图片描述

#include <stdio.h>
#include <string.h>

int main()
{
    FILE *fp = fopen("./bite", "wb+");
    if (fp == NULL) {
        perror("fopen error");
        return -1; 
    }   
	
	// 0 表示指针指向文件的开始进行读写
    fseek(fp, 0, SEEK_SET);
    char *data = "linux so easy!\n";
   
    size_t ret = fwrite(data, 1, strlen(data), fp);
    if (ret != strlen(data)) {
        perror("fwrite error");
        return -1; 
    }   
    fseek(fp, 0, SEEK_SET);//跳转读写位置到,从文件起始位置开始偏移0个字节
    char buf[1024] = {0};
    //size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
    ret = fread(buf, 1, 1023, fp);//因为设置读取块大小位1,块个数为1023因此fread返回值为实际读取到的数据长度
    
    if (ret == 0) {
        if (ferror(fp)) //判断上一次IO操作是否正确
            printf("fread error\n");
        if (feof(fp)) //判断是否读取到了文件末尾
            printf("read end of file!\n");
        return -1; 
    }   
    
    printf("%s", buf);
    fclose(fp);
    return 0;
}

3.系统调用接口的讲解

  • 为什么要有系统调用呢?
    🐧Ⅰ.我们对文件进行读写操作,文件是存储在磁盘中的,而磁盘是硬件,所以向文件写入本质是向硬件写入,我们作为一个用户,操作系统绝对不允许我们对硬件直接进行访问,所以操作系统为我们提供系统调用以便我们能够访问文件。

3.1 系统调用函数的讲解
3.1.1 open ( ) 函数的讲解

🐧① 语法:
在这里插入图片描述
🐧② 参数 flags 的详解

flags 表示以什么样的方式打开文件, O_RDONLY(只读), O_WRONLY(只写), or O_RDWR(读写)O_APPEND(追加方式打开)O_TRUNC(清空文件,重新写入)O_CREAT(该文件不存在就创建该文件)

具体怎么使用呢? ----- 涉及到一个位图的概念,这些 O_RDONLY(只读)已经被宏定义成为了一个值,这个值代表在二进制下某一位数字为1,然后用 |(与)操作就可以把几种方式联系到一起了;

🐧③ 参数 mode 的介绍

参数 mode 指定创建新文件时的文件权限。当参数 flags 指定标志位 O_CREAT O_TMPFILE 的时候,必须指定参数 mode,其他情况下忽略参数 mode。


3.1.2 write ( ) 函数的讲解

写入失败则返回 -1

在这里插入图片描述


3.1.3 lseek ( ) 函数的讲解

🍎Ⅰ.为什么要用 lseek ( ) 函数呢? 因为我们在使用 write ( ) 函数之后,文件的读写位置就停在了写完之后\0位置,我们再次对文件进行读取的时候就什么也读不到了,所以需要用 lseek ( ) 函数来移动文件的读写位置;

在这里插入图片描述


3.1.2 read ( ) 函数的讲解

在这里插入图片描述

3.2 用系统调用读写文件
  • 要求如下三点:
    🐧Ⅰ.对 open, read, write, lseek, close等函数的使用:

    🐧Ⅱ.使用代码打开当前路径下的“bite”文件(如果文件不存在在创建文件),向文件当中写入“i like linux!”。

    🐧Ⅲ.在从文件当中读出文件当中的内容, 打印到标准输出当中; 关闭文件描述符
#include <stdio.h>
#include <unistd.h>//是close, write这些接口的头文件
#include <string.h>
#include <fcntl.h>//是 O_CREAT 这些宏的头文件
#include <sys/stat.h>//umask接口头文件


int main()
{
    //将当前进程的默认文件创建权限掩码设置为0--- 并不影响系统的掩码,仅在当前进程内生效
    umask(0);
    //int open(const char *pathname, int flags, mode_t mode);
    int fd = open("./bite", O_CREAT|O_RDWR, 0664);
    if(fd < 0) {
        perror("open error");
        return -1; 
    }   
    char *data = "i like linux!\n";
    
    //ssize_t write(int fd, const void *buf, size_t count);
    ssize_t ret = write(fd, data, strlen(data));
    if (ret < 0) {
        perror("write error");
        return -1; 
    }   
    
    //off_t lseek(int fd, off_t offset, int whence);
    lseek(fd, 0, SEEK_SET);
    char buf[1024] = {0};
    
    //ssize_t read(int fd, void *buf, size_t count);
    ret = read(fd, buf, 1023);
    if (ret < 0) {
        perror("read error");
        return -1; 
    }else if (ret == 0) {
        printf("end of file!\n");
        return -1; 
    }   
    printf("%s", buf);
    close(fd);
    return 0;
}

  • 25
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

未来可期LJ

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

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

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

打赏作者

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

抵扣说明:

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

余额充值