【Linux】基础IO

前言

首先我们针对文件的几个概念进行重新思考:

  1. 空文件也占据空间
  2. 文件 = 内容 + 属性
  3. 文件操作 = 对内容 | 对属性 | 对内容和属性 的操作
  4. 使用文件必须用路径,以确保其唯一性
  5. 如果没有指明路径,则在当前路径下查找
  6. 我们在代码中使用了语言对应的文件操作函数或者使用了系统调用级别的接口来操作文件,但是如果这些程序不运行,那么文件并不会被对应函数所修改,因为文件操作是进程对文件的操作,没有运行的程序并不会修改文件。
  7. 一个文件要被访问,必须要先打开。

我们在学习c语言的过程中会学到很多的文件接口,比如fopen、flose、fwrite、fread、fseek等等,但是其他语言也有他们自己的一套文件操作接口,所以在操作系统面前,这些语言都是一视同仁的,因为想要在操作系统上进行操作,就必须使用操作系统的接口,所有语言的文件操作接口都是对系统层面接口的封装。系统调用的文件操作接口包括open、read、write、lseek、close等。

open

linux给我们提供了两种open,如图所示:
在这里插入图片描述
分别是两个参数和三个参数的接口,区别在于第三个参数。第一个参数不难理解,就是要打开文件的名称,这个名称要带有目录,如果不写目录,则会在当前路径下查找;第二个参数其实对应的就是C语言中文件操作接口中的”r“、”w“、”a“等参数,但是在这里我们用二进制位来进行标识:
在这里插入图片描述
如图所示,表右侧的参数就对应左侧c语言中不同读写功能,他们之所以通过按位或来连接,就是因为他们每个参数都只用一位二进制位来表示,并且他们每个参数的二进制位均出现在不同位置上以方便按位或操作,比如O_WRONLY就是write only的含义,相应O_RDONLY、O_RDWR、O_TRUNC、O_APPEND分别就是只写,读写,写前清空,追加等含义,在调用open接口时要指明使用的方法;前面两个参数交代完毕,第三个参数其实是对应文件的权限,如果文件已经存在,那么这个参数可以省略,但如果文件不存在,这个参数就必须要有,并且这个参数是服从文件创建的umask掩码的,如果想不受系统umask影响,则需要在open前自行定义。

read

linux下给我们提供的read接口如图所示:
在这里插入图片描述
三个参数的含义分别是:参数一为文件描述符,也就是我们刚刚open接口调用的返回值;第二个参数是我们要将读到的内容写到哪里,第三个参数是我们要写的长度。比如以下代码:

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define FILE_NAME "log.txt"
int main()
{
	int fd = open(FILE_NAME, O_RDONLY, 0666);
	if (fd < 0)
	{
		perror("open");
		return 1;
	}

	char Buffer[1024];
	ssize_t ret = read(fd, Buffer, sizeof(Buffer) - 1);
	if (ret > 0) Buffer[ret] = 0;
	printf("%s", Buffer);

	close(fd);
	return 0;
}

输出结果为:
在这里插入图片描述

write

linux提供的接口参数如下:
在这里插入图片描述
该接口的第一个参数是一个文件描述符,和read接口相同,第二个参数是要写入的地方,第三个是写入的长度,比如有以下代码:

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define FILE_NAME "log.txt"
int main()
{

    int fd = open(FILE_NAME, O_WRONLY | O_CREAT | O_APPEND, 0666);
    if (fd < 0)
    {
        perror("open");
        return 1;
    }

    int cnt = 5;
    char Out_Buffer[10];
    while (cnt)
    {
        sprintf(Out_Buffer, "%s:%d\n", "aaaaa", cnt--);
        printf("%s", Out_Buffer);
        write(fd, Out_Buffer, strlen(Out_Buffer));
    }
    close(fd);
    return 0;
}

这段代码会向打开的文件中写入五行数据,执行结果如下:
在这里插入图片描述

执行后,可以看到输出内容也输入到了文件之中。

close

此接口的含义就比较简单了,它的作用就是关掉对应的文件描述符:
在这里插入图片描述
调用时输入对应的文件描述符即可关闭对应文件。

文件描述符

上面的许多接口中都提到了文件描述符,文件描述符是什么呢?
文件描述符从表面上看是从0开始的一连串连续的整数,在C语言中,文件描述符0、1、2分别被标准输入(stdin)、标准输出(stdout)和标准错误(stderr)占据,如果要通过系统调用open打开其他的文件,文件描述符会从3开始往后依次赋值。文件描述符底层对应的其实是struct file_struct的下标,当有其他文件被打开时,就会在这个结构体对应的数组里加入一个新的变量,这个变量指向的就是新打开的文件。我们还可以通过dup系列函数对数组里指向的内容进行重定向,比如可以使stdout(也就是1)指向open接口的返回值以完成重定向,这里的重定向包括输入重定向、输出重定向、追加重定向。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值