知识归纳&学习收获
I/O库函数
简介:首先要了解系统调用与库函数。系统调用指运行在用户空间的程序向操作系统内核请求需要更高权限运行的服务。库函数可能调用封装了一个或几个不同的系统调用,也可能直接提供用户态服务。简单来描述:库函数是对系统调用的一层封装。系统调用作为内核提供给用户程序的端口,但有时我们要更复杂的处理,有更人性化的需要,我们把这些处理过程封装成一个函数放入库就是库函数。
I/O库函数与系统调用的区别
-
系统调用运行在内核空间而库函数运行在用户空间。
因为系统调用属于内核,和库函数不属于内核。因此,如果当用户态进程调用一个系统调用时,CPU需要将其切换到内核态,并执行一个内核函数。 -
内核调用都返回一个整数值,而库函数并非一定如此。
在内核中,整数或0表示系统调用成功结束,而负数表示一个出错条件。 -
库函数移植性好,而系统调用依赖于内核不保证移植性。
-
系统调用运行时间属于系统时间,库函数运行时间属于用户时间
I/O库函数算法&实践
-
fread()算法
fread可以读二进制文件,用字符方式不一定能读完整个文件,可以用二进制方式。fread()一方面接受来自用户程序的调用,另一方面向操作系统内核发出read()系统调用,所有fread()处理都在用户模式映像中执行。
file文件内容如下:
代码如下:
运行结果:
-
fwrite()算法
fwrite()算法与fread()算法数据传输方向不同。fwrite()将数据写入内部缓存区,调整缓冲区的指针、计数器和状态变量。 -
fclose()算法
fclose()首先关闭文件流的局部缓冲区,然后会发出close(fd)系统调用来关闭FILE结构体中的文件描述符,最后会释放FILE结构体,将FILE指针重置为NULL。
I/O库模式
-
“r”、“w”、“a”表示读、写、追加。
-
“r+”表示读/写,不会截断文件。
-
“w+”表示读/写,但是会先截断文件;如果文件不存在,会创建文件。
-
“a+”表示通过追加进行读/写;如果文件不存在,会创建文件。
字符模式I/O
#include <studio.h>
FILE *fp,*gp;
int main(){
int c;
fp=fopen("source", "r");
gp=fopen("target", "w");
while ( (c==getc(fp)) !==EOF )
putc(c,gp);
fclose(fp); fclose(gp);
}
行模式I/O
#include <stdio.h>
FILE *fp,*gp;
char buf[256]; char *s="this is a string";
int main()
{
fp = fopen("src", "r");
gp = fopen("dest", "w");
fgets(buf,256,fp);
fputs(buf,gp);
}
格式化I/O
格式化输入:
scanf(char *FMT, &items);
fscanf(fp, char *FMT, &items);
格式化输出:
printf(char *FMT, items);
fprintf(fp, char *FMT, items);
文件流缓冲
- _IONBUF:无缓冲 (从非缓冲流中写入或者读取的字符将尽快单独传输到文件或从文件中传输。)
- _IOLBUF:行缓冲 (遇到换行符时,写入行缓冲流的字符以块的形式传输。)
- _IOFBUF:全缓冲 (写入全缓冲流或者从中读取的字符以块大小传输到文件或从文件传输。)
编程项目:编写类printf()函数
项目步骤如下
- 项目规范使用putcahr()实现,并且忽略保留的宽度和精度
- 基本代码
- myprintf()的算法
- 项目改进
参考资料:
Linux 文件操作——系统调用和标准I/O库
Linux 库函数与系统调用的关系与区别
(引用了课本中的代码)