文件IO的概念及常用函数

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

文件输入输出(File Input/Output,简称文件I/O)是编程中一个基本且重要的概念。它涉及到在程序和存储设备(如硬盘、闪存驱动器等)之间读取或写入数据的过程。在不同的编程语言中,文件I/O的实现方式会有所不同,但基本原理相似。本文以C语言为主


一、文件IO是什么?

文件IO就是在POSIX(可移植操作系统接口)中定义的一组输入输出的函数。涉及操作系统和应用程序之间的交互,用于读取和写入存储在永久性存储介质(如硬盘、SSD、USB闪存盘等)上的数据。

特点:

  • 没有缓存机制
  • 围绕文件描述符进行操作,相当于标准IO中的流(FILE*),文件描述符是正整数。
  • 默认打开三个描述符
    • 标准输入 0
    • 标准输出 1
    • 标准错误 2
  • 除目录文件,其他类型文件都可以操作

二、函数

1.打开文件

需要引用三个头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname,int flags,...)
功能:
	打开文件
参数:
	pathname:文件路径名
	flags:文件打开方式
	...:第三个参数在打开方式为创建时,用来设置文件权限。后面会细说
返回值:
	成功:文件描述符
	失败:-1

打开方式有以下几种

  • O_RDONLY 只读
  • O_WRONLY 只写
  • O_RDWR 读写
  • O_CREAT 创建
  • O_TRUNC 清空
  • O_APPEND 追加

在程序中可以看到这是一组宏定义
在这里插入图片描述
也可以以组合的方式,实现类似标准IO打开文件的功能

文件IO标准IO功能
O_RDONLYr只读
O_RDWRr+读写
O_WRONLY|O_TRUNC|O_CREATw写,打开始会覆盖原文,没有对应文件则创建文件
O_RDWR|O_TRUNC|O_CREATw+读写,打开始会覆盖原文,没有对应文件则创建文件
O_APPEND|O_CREAT|O_WRONLYa从文档末尾开始写入,没有对应文件则创建文件
O_RDWR|O_APPEND|O_CREATa+从文档末尾开始读写,没有对应文件则创建文件

第三个参数

设置文件权限,在创建文件时才需要添加

//创建一个test文件,文件权限为666,0开头表示八进制数
open("./test",O_CREATE|O_REWR,0666);

这里我们将文件权限值设为了666(所有人可读写),但实际的情况是664,因为这个函数会自动将我们的权限值与上一个~umask

umask的值为 0002
实际情况为:
	0666&(~umask)
	需要按二进制运算
	110 110 110 &(~(000 000 010))
	110 110 110
   &111 111 101
   =110 110 100
   =>664

所有在这个函数中无论我们怎样设置权限,其他分组的用户都无法获得写的权限,

关闭文件

int close(int fd);
功能:
	关闭文件
参数:
	文件描述符

文件读写操作

头文件为#include <unistd.h>

读操作

ssize_t read(int fd, void *buf, size_t count);
功能:
	从一个已打开的可读文件中读取数据
参数:
	fd		文件描述符
    buf  	存放位置
    count  	期望的个数
返回值:
	成功:
		实际读到的个数
    失败:
    	返回-1:表示出错,并设置errno号
      	返回0:表示读到文件结尾

写操作

ssize_t write(int fd, const void *buf, size_t count);
功能:
	向指定文件描述符中,写入 count个字节的数据。
参数:
	fd   文件描述符
	buf   要写的内容
	count  期望值
返回值:
	成功:实际写入数据的个数
	失败  : -1

例子

//已有文件test1,里面有一段文本,我们将他读取出来,再写入新的文本
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
    int fp;
    char buf1[32] = "";
    char buf2[32] = "Is a rookie\n";
    // 以读写方式打开文件,返回文件描述符号
    fp = open("./test1",O_RDWR);
    //期望读取32个
    size_t num = read(fp,buf1,32);
    printf("实际读取个数%ld\n读取内容:%s",num,buf1);
    // 期望写入32个
    num = write(fp,buf2,32);
    printf("实际写入个数%ld\n写入内容:%s",num,buf2);

}

运行结果
在这里插入图片描述
我们的字符串数组buf2 的实际内容长度明显不足32,但程序程序还是按照我们的要求写入了32个字符,那多出来的那一部分是什么
再让我们看看目标文档
在这里插入图片描述
通过以上结果我们可以看到

  • 读取的期望值是我们一次所能读取到的最大值,当目标文本内容不足时,会按实际长度读取
  • 写入时的期望值就是要写的个数,当目标数据不足时,会添加一些我们看不懂的东西

2.文件定位操作

每次对文件进行读取或写入操作时,文件光标都会向后移动对应的长度。如果想让光标移动到指定位置进行读写操作,需要使用定位函数

off_t lseek(int fd, off_t offset, int whence);
功能:
	设定文件的光标位置
参数:
	fd:文件描述符
    offset:偏移量  
       	正数:向文件结尾位置移动
        负数:向文件开始位置
    whence  相对位置
        SEEK_SET   开始位置
        SEEK_CUR   当前位置
        SEEK_END   结尾位置
返回值:成功:文件的当前位置


总结

文件IO的操作与标准IO类似,可以对比理解。

  • 19
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值