文章目录
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(只写), orO_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;
}
                

