当前位置: 首页 > news >正文

Linux应用软件编程---文件操作3(文件IO及其指令、文件定位函数lseek、文件IO与标准IO的比较、缓冲区)

目录

一、文件IO

1、文件IO的操作指令

2、文件IO的打开方式   

3、标准IO 和 文件IO 打开方式的对应关系

4、文件描述符

5、open 指令

        1)需包含的头文件

        2)指令说明

6、close  指令

        1)需包含的头文件

        2)指令说明

7、read  指令

8、write 指令

9、练习例题

       1)使用 write 指令将数据输入 1.txt 文件中的练习

        2)使用文件IO实现cat功能

        3)使用文件IO实现copy功能

二、文件定位函数 (lseek)

1、函数概念

2、应用

三、标准IO与文件IO的对比

1、标准IO

2、文件IO

3、二者结构图

四、缓冲区

1、行缓冲

2、全缓冲

3、无缓冲

一、文件IO

        文件IO(系统调用)是Linux内核专门为应用层提供的文件操作方法。

1、文件IO的操作指令

        1)打开文件  open

        2)读、写文件  read/write

        3)关闭文件  close

2、文件IO的打开方式   

打开方式含义
O_RDONLY只读方式
 O_WRONLY只写方式
 O_RDWR可读可写
O_CREAT创建文件
 O_TRUNC清空文件
O_APPEND追加写

3、标准IO 和 文件IO 打开方式的对应关系

标准IO文件IO
“r”O_RDONLY 
"r+" O_RDWR
"w"     O_WRONLY | O_CREAT |  O_TRUNC
"w+" O_RDWR | O_CREAT |  O_TRUNC
"a" O_WRONLY | O_APPEND | O_CREAT
"a+" O_RDWR |  O_APPEND | O_CREAT

        *其中,文件IO 中的 “ | ” 是 “ 按位与 ” 运算符。

4、文件描述符

 文件描述符是指操作系统中已打开文件的标识符。是一种小的、非负的整形数据
        范围:0-1023 (总共1024个)
        分配原则:最小未被使用原则(即从0开始往后,哪个部分没有被使用,先使用哪个部分)
        文件描述符泄露:已打开的文件,使用完时,未及时关闭。

        文件IO中的文件描述符的作用相当于标准IO中的文件流指针。

        操作系统已经默认打开的三个文件占用了0、1、2这三个文件描述符:

标准IO含义文件IO
FILE *----------------->int
stdin标准输入设备0
stdout标准输出设备1
stderr标准出错设备2

5、open 指令

        1)需包含的头文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

        2)指令说明

          int open(const char *pathname, int flags);
          int open(const char *pathname, int flags, mode_t mode);
          功能:打开文件并获得一个文件描述符
          参数:
                 pathname:要打开的文件的文件名
                 flags:打开方式
                 mode:文件读写执行操作权限(当flag中有O_CREAT标志时,必须要增加mode操作权限,为八进制书写格式)

       返回值:
                成功:文件描述符 
                失败:-1

        *关于 mode 的计算方式为(mode & ~umask),mode 和 umask(码值) 的反 进行按位与操作,码值可通过在终端输入“ umask ” 进行查看。

        例如:码值为 0002(000 000 000 010) 时

                    r w -  r w -  r -  -      (110 110 100) & ~(000 000 010)
                   1 1 0 1 1 0 1 0 0 --->0664

         即“ rw-rw-r-- ” 权限的mode值为 0664。

6、close  指令

        1)需包含的头文件

          #include <unistd.h>

        2)指令说明

           int close(int fd);
          功能:关闭文件

           fd:使用open指令打开的文件

7、read  指令

        ssize_t read(int fd, void *buf, size_t count);
        功能:从文件中读取数据
        参数:
            fd:文件描述符
            buf:存储数据的空间首地址
            count:希望读取的字节数
       返回值:
           成功:实际读到的字节数
           失败:-1
           读到文件末尾:0

8、write 指令

        ssize_t write(int fd, const void *buf, size_t count);
        功能:向文件中写入数据
        参数:
              fd:文件描述符
              buf:要写入的数据的首地址
              count:要写入的字节数

        返回值:
              成功:实际写入的字节数
              失败:-1

        例如:在终端打印“ hello world ”,write代码为:write(1, "hello world", 11)  。

9、练习例题

        下述例题均需包含以下头文件(封装为 “ head.h ” 头文件):

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

       1)使用 write 指令将数据输入 1.txt 文件中的练习

#include "head.h"int main(int argc, const char *argv[])
{int fd = open("./1.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664);if (-1 == fd){printf("open error\n");return -1;}char *pstr = "hello world";char str[32] = {"how are you"};write(fd, str, strlen(str));write(fd, "hello world", 11);write(fd, pstr, strlen(pstr));close(fd);return 0;
}

        2)使用文件IO实现cat功能

#include "head.h"int main(int argc, const char *argv[])
{if (argc < 2){printf("Usage : ./a.out <filename>\n");return -1;}int fd = open(argv[1], O_RDONLY);if (fd < 0){printf("open error\n");return -1;}char buff[1024] = {0};while (1) //防止文件大于 1024 ,循环读取{ssize_t cnt = read(fd, buff, sizeof(buff));if (0 == cnt){break;}else if (-1 == cnt){printf("read error\n");break;}write(1, buff, cnt);}close(fd);return 0;
}

        3)使用文件IO实现copy功能

#include "head.h"int main(int argc, const char *argv[])
{if (argc < 3){printf("Usage: ./a.out <srcfile> <dstfile>\n");return -1;}int fdsrc = open(argv[1], O_RDONLY);int fddst = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0664);if(-1 == fdsrc || -1 == fddst){printf("open error\n");return -1;}char buff[1024] = {0};while (1){ssize_t cnt = read(fdsrc, buff, sizeof(buff));if (cnt <= 0){break;}write(fddst, buff, cnt);}close(fdsrc);close(fddst);return 0;
}

二、文件定位函数 (lseek)

1、函数概念

        off_t lseek(int fd, off_t offset, int whence);
        功能:文件读写位置定位
        参数:
                fd:文件描述符
                offset:偏移量(字节)
                whence:要偏移的相对位置
                    SEEK_SET:文件开头位置
                    SEEK_CUR:文件当前读写位置
                    SEEK_END:文件末尾
        返回值:
               成功:返回当前读写位置到文件开头的偏移量
               失败:-1

2、应用

   例如: 求文件大小:
               off_t len = lseek(fd, 0, SEEK_END);
        l      seek(fd, 0, SEEK_SET);  //将指针指向文件开头 (复位) 

#include "head.h"int main(int argc, const char *argv[])
{int fd = open("./1.txt", O_WRONLY | O_TRUNC | O_CREAT, 0664);if (fd < 0){printf("open error\n");return -1;}off_t offset = lseek(fd, 10, SEEK_SET); //从文件开头偏移10输入'A'printf("offset = %ld\n", offset);write(fd, "A", 1);offset = lseek(fd, 0, SEEK_CUR);//从当前位置偏移0printf("offset = %ld\n", offset);offset = lseek(fd, 0, SEEK_SET);//复位printf("offset = %ld\n", offset);offset = lseek(fd, 0, SEEK_END);//文件末尾printf("offset = %ld\n", offset);lseek(fd, 0, SEEK_SET); //复位close(fd);return 0;
}

三、标准IO与文件IO的对比

1、标准IO

        1)属于C库函数,移植性强
        2)标准IO是系统调用的一次封装,增加了缓冲区,目的是提高数据读写的效率
        3)标准IO主要用在对普通文件的操作

2、文件IO

        1)属于系统调用,只能用于Linux操作系统,移植性弱
        2)文件IO无缓冲区
        3)文件IO主要应用在对硬件的操作的,也可以操作普通文件  

3、二者结构图

四、缓冲区

       缓冲区分为 行缓冲、全缓冲、无缓冲 三部分。

1、行缓冲

      大小默认为 1k(1024个字节),一般应用于:人机交互界面、终端
      缓冲区被刷新的方法:
       1)程序结束,自动刷新缓冲区
       2)遇到\n刷新
       3)fflush(文件流指针) 强制刷新
       4)缓冲区满刷新

2、全缓冲

      大小默认为 4k(4096个字节),一般应用于:文件缓冲区
      缓冲区被刷新的方法:
        1)程序结束,自动刷新缓冲区
        2)fflush()强制刷新
        3)文件关闭刷新
        4)缓冲区满刷新

3、无缓冲

        大小为 0k(0个字节),一般应用于:出错信息对应的设备
      eg.  stderr ---> 无缓冲

【END】

http://www.dtcms.com/a/328542.html

相关文章:

  • archlinux中VLC无法播放视频的解决办法
  • 【Datawhale夏令营】多模态RAG学习
  • 关于Linux编程3:fread/fwrite/流的定位/文件IO
  • 存储过程作为系统逻辑核心的架构思考 —— 以 SaaS 系统为例
  • 电商双 11 美妆数据分析:从数据清洗到市场洞察
  • 生产环境中Kubernetes Pod 安全上下文与策略的实战经验分享
  • nt!MmCreatePeb函数分析之peb中OSMajorVersion的由来
  • Flutter ExpansionPanel组件(可收缩的列表)
  • 【入门系列】图像算法工程师如何入门计算机图形学?
  • 数据分析基本内容(第二十节课内容总结)
  • MCU外设初始化:为什么参数配置必须优先于使能
  • redis的过期策略和定时器
  • 支持任意 MCP 协议的客户端
  • SQL180 每类试卷得分前3名
  • Mybatis源码解读-Plugin插件源码
  • (C++)继承全解析及运用
  • Labelme从安装到标注:零基础完整指南
  • MySQL基础面试
  • Springboot整合Thrift
  • 移动端网页调试实战,键盘弹出与视口错位问题的定位与优化
  • 汉高携手SAP推出AI驱动的退换货与争议管理解决方案
  • 赛灵思ZYNQ官方文档UG585自学翻译笔记:UART Controller,通用异步收发传输器控制器
  • Vue接口平台十三——测试记录
  • Ubuntu 全盘备份
  • 九尾狐未来机械晶核技术
  • k3s部署
  • 电脑硬件详解
  • ZYNQ AXI-GPIO学习——ZYNQ学习笔记8
  • 学习游制作记录(背包UI以及各种物品的存储)8.12
  • kafka 消费者组的概念是什么?它是如何实现消息的点对点和发布/订阅模式?