20211205ZX

导航

信息安全系统设计与实现

一.

9.1 I/O库函数

I/O库函数是在C和C++编程中被广泛使用的文件操作函数,用于进行输入和输出操作。它们是构建在系统调用上面的高级接口,提供了更方便和高效的文件操作方式。

9.2 I/O库函数与系统调用

这些函数提供了更高级别的抽象,使文件操作更容易管理和使用。

库函数(Library Function)

库函数是由编程语言提供的高级抽象接口,封装了底层的系统调用,提供更简单、易用的接口供开发者使用。

库函数通常以函数库(library)的形式存在,开发者可以通过包含头文件并链接函数库来使用库函数。

库函数的实现通常是使用系统调用来完成底层的文件操作,因此库函数是建立在系统调用之上的。

系统调用(System Call)

系统调用是操作系统提供的底层接口,可以让用户程序与操作系统内核进行交互,执行各种系统级任务,包括文件操作。

系统调用通常以函数调用的形式存在,用户程序通过调用系统调用来请求操作系统执行特定的功能。

系统调用提供了更底层和直接的操作文件的能力,但使用起来相对较麻烦,需要开发者处理更多的细节和错误检查。

区别与联系

库函数是建立在系统调用之上的高层接口,提供了更简洁、易用的文件操作方式,隐藏了底层细节,方便开发者使用,但功能方面可能不如系统调用灵活。

系统调用提供了底层的操作能力,可直接与操作系统内核进行交互,更加灵活和强大,但使用时需要开发者自行处理底层细节和错误处理。

库函数的实现通常依赖于系统调用,库函数在内部调用适当的系统调用来实现文件操作的具体功能。

在文件操作中,开发者可以根据需求选择使用库函数或系统调用。库函数一般更适合一般的文件操作和简单的应用程序,而系统调用则更适合对文件进行更底层、细粒度的操作或需要与底层操作系统进行交互的场景。

9.3 I/O库函数的算法

I/O库函数背后有不同的实现算法:

对于fread()算法:fread()函数在用户程序中被调用,它将向操作系统内核发送read()系统调用,以从文件中读取指定数量的数据,并将数据存储到指定的内存位置中。

对于fwrite()算法:与fread()类似,但数据传输方式有所不同。当缓冲区为空时,调用fwrite()将数据写入内部缓冲区,并调整缓冲区指针、计数器和状态变量,跟踪缓冲区中的字节数。当缓冲区满时,会发出write()系统调用,将整个缓冲区写入操作系统内核。

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

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

在进行文件操作时,你可以根据自己的需求选择使用I/O库函数或系统调用。以下是一些关于文件操作的常见用法:

使用fopen()函数时,可以通过模式参数来指定文件的打开方式。常用的模式参数包括:"r"表示只读,"w"表示只写,"a"表示追加。每个模式字符串可以包含一个+号,表示同时可读可写,或在写入或追加时如果文件不存在则创建文件。

"r+"表示可读可写,打开文件时不会截断文件。

"w+"表示可读可写,打开文件时会先截断文件;如果文件不存在,会创建文件。

"a+"表示可读可写,通过追加的方式进行操作;如果文件不存在,会创建文件。

9.5 I/O模式库

除了二进制模式的I/O,C语言还提供了字符模式的I/O函数,用于按字符为单位进行文件操作。以下是一些常见的字符模式I/O函数:

int fgetc(FILE *fp):从文件中读取一个字符并返回其ASCII码值。通常,EOF(文件结束符)用于表示文件的末尾。

int ungetc(int c, FILE *fp):将之前通过fgetc()获取的字符重新放回流中,以便稍后再次读取。

int fputc(int c, FILE *fp):将字符写入文件中。

这些函数通常用于文本文件的读取和写入操作,而不是用于处理二进制数据。

除了上述函数,还有一些其他有用的I/O库函数,包括:

fseek()、ftell()、rewind():用于更改文件流中的读/写字节位置,获取当前位置以及将文件指针重置为文件开头。

feof()、ferror()、fileno():用于检查文件流的状态,判断文件是否到达末尾或发生错误,并获取文件描述符。

fdopen():用于使用文件描述符打开文件流。

freopen():重新打开一个现有的流,以便使用新的文件名。

setbuf()、setvbuf():用于设置文件流的缓冲机制。

popen():用于创建管道,复制子进程以调用shell执行命令。

这些函数在文件操作中非常有用。

9.6 文件流缓冲

文件流有不同的缓冲模式,如:

无缓冲:从非缓冲流中写入或读取的字符将立即独立传输到文件或从文件中传输。例如,文件流stderr通常是无缓冲的,所有输出会立即发送。

行缓冲:写入行缓冲流的字符将以块的形式传输,直到遇到换行符为止。例如,文件流stdout通常是行缓冲的,数据会逐行输出。

全缓冲:写入全缓冲流或从中读取的字符将以块的大小传输到文件或从文件中传输。这是文件流的默认缓冲方案。

通过调用setvbuf(FILE *stream, char *buf, int mode, size_t size),你可以在使用fopen()创建文件流后设置缓冲区、缓冲区大小和缓冲模式。常用的缓冲模式包括_IONBF(无缓冲)、_IOLBF(行缓冲)和_IOFBF(全缓冲)。

9.7 变参函数

I/O库函数中,存在一类特殊的函数称为变参函数(Variadic Function),它们可以接受可变数量的参数。C语言和C++都支持这种类型的函数声明和调用。其中,printf()就是一个典型的变参函数。

变参函数的声明需要至少一个固定参数,然后通过使用省略号(…)表示可以接受更多的可变参数。这些可变参数的类型和数量没有限制,可以根据调用时提供的实际参数进行灵活处理。

在使用变参函数时,开发者需要使用一些特定的宏或函数来处理这些可变参数,如va_start()、va_arg()和va_end()等。这些函数提供了一种方式来逐个访问和获取可变参数的值。

 

二.

 

 

 

 

三.

 

 

 

posted on 2023-09-17 22:49  20211205ZX  阅读(17)  评论(0编辑  收藏  举报