首页 > 系统相关 >《Unix/linux系统编程》教材第9章学习笔记

《Unix/linux系统编程》教材第9章学习笔记

时间:2023-09-17 13:34:49浏览次数:34  
标签:文件 调用 缓冲 编程 fread Unix FILE linux 缓冲区

结构化教材内容

第9章:I/O库函数

I/O库函数与系统调用

  • 系统调用是文件操作的基础,但它们只支持数据块的读/写。
  • 系统调用函数:open()、read()、write()、lseek()、close();
  • I/O库函数:fopen()、fread()、fwrite()、fseek()、fclose();
  • I/O库函数的根都在对应的系统调用函数中,例fopen()依赖于open()。

I/O库函数的算法

  • fread算法
  1. 第一次调用fread()时,FILE结构体缓冲区是空的,fread()使用保存的文件描述符fd发出一个
    n = read(fd, fbuffer, BLKSIZE);
    系统调用,用数据块填充内部的fbuf[]。然后它会初始化fbuf[]的指针、计数器和状态变量,表明内部缓冲区有一个数据块。接着,通过将数据赋值到程序的缓冲区,尝试满足来自内部缓冲区的fread()调用。如果内部缓冲区没有足够的数据,则会再发出一个read()系统调用来填充内部缓冲区,将数据从内部缓冲区传输到程序缓冲区,直到满足所需的字节数(或者文件无更多数据)。将数据复制到程序的缓冲区之后,它会更新内部缓冲区的指针、计数器等,为下一个fread()请求做好准备。然后它会返回实际读取的数据对象数量。
  2. 在随后的每次fread()调用中,它都尝试满足来自FILE结构体内部缓冲区的调用。当缓冲区变为空时,它就会发出read()系统调用来重新填充内部缓冲区。因此fread()一方面接受来自用户程序调用,另一方面向操作系统内核发出read()系统调用。除了read()系统调用外,所有fread()处理都在用户模式映像中执行。它只在需要时才会以一种最搞笑匹配文件的方式进入操作系统内核,并且会提供自动缓冲机制。
  • fwrite算法
    与fread()算法类似,只是数据传输方向不同。最开始FILE结构体内部缓冲区为空,每次调用fwrite()时,将数据写入内部缓冲区,并调整缓冲区的指针、计数器和状态变量,以跟踪缓冲区中的字节数。如果缓冲区已满,则发出write()系统调用,将整个缓冲区写入操作系统内核。

  • fclose算法:
    若文件以写方式打开,fclose()会先关闭文件流的局部缓冲区。然后发出close(fd)系统调用来关闭FILE结构体中的文件描述符,最后释放FILE结构体并将FILE指针重置为NULL。

I/O库模式
fopen()模式参数可指定为:"r"、"w"、"a",分别代表读、写、追加,后面添加"+",表示同时读写,或者在写入、追加情况下,若文件不存在则创建文件。
"r+":表示读/写,不会截断文件。
"w+":表示读/写,但是会先截断文件;如果文件不存在,会创建文件。
"a+":表示通过追加进行读/写;如果文件不存在,会创建文件。

  • 字符模式I/O:
int fgetc(FILE *fp);
int ungetc(int c, FILE *fp);
int fputc(int c, FILE*fp);

当fp=stdin或stdout,可能会使用c=getchar();putchar(c);来代替。

  • 行模式I/O:
char *fgets(char *buf, int size, FILE *fp);
int fputs(char *buf, FILE *fp);

当fp=stdin或stdout时也可以使用
gets(char *buf);
puts(char *buf);

  • 格式化I/O:
    格式化输入:(FMT=格式字符串)
scanf(char *FMT, &items);
fscanf(fp, char *FMT, &items);

格式化输出:

printf(char *FMT, items);
fprintf(fp, char *FMT, items);
  • 内存中的转换函数
sscanf(buf, FMT, &items);
sprintf(buf, FMT, items);
  • 其他I/O库函数
    fseek()、ftell()、rewind():更改文件流中的读/写字节位置。
    feof()、ferr()、fileno():测试文件流状态。
    fdopen():用文件描述符打开文件流。
    freopen():以新名称重新打开现有的流。
    setbuf()、setvbuf():设置缓冲方案。
    popen():创建管道,复刻子进程来调用sh。

  • 限制混合fread-fwrite
    当某文件流同时用于读/写时,就会限制使用混合fread()和fwrite()调用。规范要求每对fread()和fwrite()之间至少有一个fseek()或ftell()。

文件流缓冲
对文件流进行读写需要遍历FILE结构体的内部缓冲区。文件流可使用三种缓冲方案中的一种:

  1. 无缓冲:从非缓冲流中写入或者读取的字符将尽快单独传输到文件或从文件中传输。
  2. 行缓冲:遇到换行符时,写入到缓冲流的字符以块的形式传输。
  3. 全缓冲:写入全缓冲或从中读取的字符以块大小传输文件或从文件传输。这是文件流的正常缓冲方案。
    通过fopen()创建文件流之后,在执行任何操作前均可发出
    setvbuf(FILE *stream, char *buf, int mode, int size)
    调用来设置缓冲区(buf),缓冲区大小(size)和缓冲方案(mode),它们必须是以下一个宏:
    _IONBF:无缓冲
    _IOLBF:行缓冲
    _IOFBF:全缓冲

变参函数
在I/O库函数中,多种不同类型的可变数量参数可以调用printf()。目前C和C++允许参数数量可变的函数,这些函数必须至少使用一个参数进行声明,后跟3个点,如:int func(int m, int n . . . )
在函数内部可以通过C语言库宏访问参数:

void va_start(va_list ap, last);
type va_arg(va_list ap, type);
va_end(va_list ap);

问题总结

文件操作都有什么?
文件操作包括打开文件、关闭文件、读取文件、写入文件、定位文件指针、删除文件和创建文件等。

二进制文件和文本文件如何转换?
二进制文件转文本文件:
使用xxd命令可以将二进制文件转换为文本文件。xxd命令会将二进制文件的内容以十六进制形式显示在终端上,并将其保存到一个文本文件中。
xxd -p binary_file > text_file
上述命令中,binary_file是要转换的二进制文件的文件名,text_file是要生成的文本文件的文件名。

文本文件转二进制文件:
使用xxd命令的-r选项可以将文本文件转换为二进制文件。
xxd -r -p text_file > binary_file
上述命令中,text_file是要转换的文本文件的文件名,binary_file是要生成的二进制文件的文件名。

数据结构如何读写
使用标准I/O库函数:可以使用标准I/O库函数(如fopen、fread、fwrite、fclose等)来打开文件、读取数据、写入数据和关闭文件。这些函数可以通过文件指针来访问文件,并使用缓冲区来读写数据。
使用系统调用:可以使用系统调用(如open、read、write、close等)来打开文件、读取数据、写入数据和关闭文件。

GPT互动提问

  • I/O库函数


  • 文件流缓冲


代码

标签:文件,调用,缓冲,编程,fread,Unix,FILE,linux,缓冲区
From: https://www.cnblogs.com/weidaixdrx/p/17708336.html

相关文章

  • linux安装nacos
    一、准备1.安装包nacos-server-2.0.3.tar.gz2.jdk1.8+环境3.mysql二、解压安装#解压tarzxvfnacos-server-2.0.3.tar.gz-C/usr/local/nacos#进入解压目录中bin文件夹cd/usr/local/nacos/nacos-server-2.0.3/bin#试运行nacos服务#启动命令(standalone代表着单机模......
  • Unix/Linux系统编程学习笔记二
    学习笔记二一、教材知识点总结1.I/O库函数程序(1)fopen()使用字符串表示模式,其中"r"表示READ"w"表示WRITE。它返回一个指向FILE结构体的指针。fopen()首先发出open()系统调用来打开文件,以获取文件描述符编号fd。如果open0系统调用失败,则fopen()会返回一个NULL指针。否则,它会......
  • Linux Shell脚本实战:让你的工作变得更轻松、更高效
    作为一名Linux工程师,会写好的脚本不仅能提高工作效率,还能有更多的时间做自己的事。最近在网上冲浪的时候,也注意收集一些大佬写过的脚本,汇总整理一下,欢迎收藏,与君共勉!查看有多少远程的IP在连接本机#!/bin/bash#!/bin/bash#查看有多少远程的IP在连接本机(不管是通过ssh......
  • 系统内存管理:虚拟内存、内存分段与分页、页表缓存TLB以及Linux内存管理
    虚拟内存虚拟内存是一种操作系统提供的机制,用于将每个进程分配的独立的虚拟地址空间映射到实际的物理内存地址空间上。通过使用虚拟内存,操作系统可以有效地解决多个应用程序直接操作物理内存可能引发的冲突问题。在使用虚拟内存的情况下,每个进程都有自己的独立的虚拟地址空间,它们......
  • 《深入LINUX内核架构》学习笔记 ——01
    模块相关的知识1.模块相较于宏内核(微内核优点)模块消除了宏内核的许多限制,包括:缺乏动态可拓展性、导致内核映像尺寸膨胀、测试新特性时必须重启系统等。2.静态链接、动态链接及模块依赖(TIPS)《深入理解计算机系统》中有这样一段话:共享库是一个目标模块,在运行或加......
  • Win32编程之文件设备(九)
    一、文件的创建CreateFile是一个WindowsAPI函数,用于创建或打开文件、设备、目录或管道。它是Windows操作系统中文件和I/O操作的基础之一。CreateFile允许你指定文件的访问方式、共享模式、创建选项等,并返回一个文件句柄,通过该句柄可以执行读取、写入、关闭等操作。以下......
  • goland dlv在远程linux里运行代码开发,并debug调适
    一、配置好ssh自动同步代码参考下面连接:https://www.cnblogs.com/haima/p/13257524.html二、配置devbug监听运行GORemote填写配置linux上运行监听服务如:上图有两种方式直接运行代码并监听dlvdebug--headless--listen=:12345--api-version=2--accept-multiclie......
  • 前端开发的未来:Web组件化与可视化编程探索
    随着互联网的快速发展,前端开发领域也日新月异。为了满足越来越多复杂的需求和提高开发效率,前端开发不断演进。本文将深入探讨前端开发的未来,重点关注Web组件化和可视化编程,这两个领域有望改变前端开发的方式。1.Web组件化的兴起Web组件化是前端开发的一个重要趋势,它旨在将Web应......
  • IFAction导出的游戏如何在linux程序下运行?
    在linux系统里,应该都自带python环境,把游戏以web方式导出,在文件夹下创建一个python文件(文件后缀以.py结束),把以下代码复制进去,#author:rkey#date:20230904#note:用于解决IFAction导出的web版游戏在linux系统下运行的问题。importtkinterastkfromthreadingimportThrea......
  • linux安装nacos
    linux安装nacos1、jdk安装1.1、准备jdk1.8安装包1.2、解压JDK安装包1.3、配置JDK变量环境1.4、刷新环境变量使其生效1.5、查看JDK是否安装成功2、安装maven2.1、首先到maven官网下载maven压缩包2.2、将下载的压缩包上传到linux的/usr/local目录2.3、解压文件2.4、配置环境变量2.5、......