第九章学习笔记

第九章学习笔记

第九章 I/O库函数

1.I/O库函数

  • 系统调用是文件操作的基础,但它们只支持数据块的读/写。I/O库函数是一系列文件操作函数。

2.I/O库函数与系统调用

  • 在Unix/Linux中,I/O库函数建立在系统调用的基础上
    • 系统调用函数:open() read() write() lseek() close()
    • I/O库函数:fopen() fread() fwrite() fseek() fclose()
    • fopen()使用字符串表示模式,在失败时会返回一个NULL指针

3.I/O库函数的算法

  1. fread算法
    在第一次调用fread()时,FILE结构体的缓冲区是是空的,fread()使用保存的文件描述符fg发出一个
n = read(fd,fbuffer,BLKSIZE);

在随后的每次调用中都尝试满足来自FILE结构体内部缓冲区的调用
2. fwrite算法

  • fwrite算法与fread算法相似,数据传输方向不同,在每次调用fwrite()时,它将数据写入内部缓冲区,并调整缓冲区的指针、计数器和状态变量,以跟踪缓冲区中的字节数。如果缓冲区已满,则发出 write()系统调用,将整个缓冲区写入操作系统内核
  1. fclose算法
  • 若文件以写的方式被打开,fcloseO会先关闭文件流的局部缓冲区。然后,它会发出一个close(fd)系统调用来关闭FILE结构体中的文件描述符。它会释放FILE结构体,并将 FILE 指针重置为 NULL。

4.使用I/O库函数或系统调用

  • fread()依赖read将数据从内核复制到内部缓冲区,然后从内部缓冲区将数据复制到程序的缓冲区。所以,它传输了两次数据。相反,read()将数据从内核直接复制到程序的缓冲区,只复制了一次。因此,对于以BLKSIZE为单位的读/写数据来说,read()本来就比fread()更高效,因为它只需要一个而不是两个复制操作。类似表述也适用于write()和 fwrite()。

5.I/O库模式

  • "r+":表示读/写,不会截断文件。
  • "w+":表示读/写,但是会先截断文件;如果文件不存在,会创建文件。
  • "a+":表示通过追加进行读/写;如果文件不存在,会创建文件。
  1. 字符模式I/O
  • fgetc()返回的是整数,而不是字符。
  • 对于fp=stdin或stdout,可能会使用c=getchar();putchar(c);来代替。
  1. 行模式I/O
char *fgets(char *buf, int size,FILE*fp)

从fp中读取最多为一行(以 结尾)的字符

int fputs(char *buf,FILE*fp)

将buf中的一行写人fp中
3. 格式化I/O

  • 格式化输入:(FMT=格式字符串)
scanf(char*FMT, &items); // from stdin
fscanf(fp,char *FMT, &items); // from file stream
  • 格式化输出:
printf(char *FMT, items); // to stdout
fprintf(fp,char *FMT, items); // to file stream
  1. 其他I/O库函数
  • fseek()、ftell()、rewind():更改文件流中的读/写字节位置
  • feof()、ferr()、fileno():测试文件流状态
  • fdopen():用文件描述符打开文件流
  • freopen():以新名称重新打开现有的流
  • setbuf0、setvbuf():设置缓冲方案
  • popen():创建管道,复刻子进程来调用sh

6.文件流缓冲

  • _IONBUF:无缓冲
  • _IOLBUF:行缓冲
  • _IOFBUF:全缓冲
  • 此外,还有其他的setbuf()函数,是setvbuf()的变体。对于行缓冲流或全缓冲流,可用fflush(stream)立即清除流的缓冲区。

7.变参函数

  • 在I/O库函数中, printf()相当独特,因为多种不同类型的可变数量参数可以调用它。C语言和C++仍然允许参数数量可变的函数。这些函数必须至少使用一个参数进行声明,后跟3个点。

8.编程项目:类printf函数

  • 在Linux中,putcher(char c)可打印一个字符
原文地址:https://www.cnblogs.com/zhangwenying/p/15312332.html