ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

第九章学习笔记

2022-09-11 13:31:10  阅读:180  来源: 互联网

标签:文件 调用 第九章 缓冲 fread 笔记 学习 read 缓冲区


第九章学习笔记

I/O库函数是一系列文件操作函数,既方便用户使用,又提高了整体效率

I/O库函数与系统调用

系统调用函数:open()、read()、write()、lseek()、close()
I/O库函数:fopen()、fread()、ferite()、fseek()、fclose()
每个I/O库函数的根都在对应的系统调用函数中。

I/O库函数的算法

(1)fread算法

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

(2)fwrite算法

与fread算法相似,只是数据传输方向不一样。

(3)fclose算法

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

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

fread()依赖read()将数据从内核赋值到内部缓冲区,然后从内部缓冲区将数据复制到程序缓冲区,他传输了两次数据相反,read()将数据从内核直接复制到程序的缓冲区,只复制一次。

I/O库模式

fopen()中的模式参数可以指定为:"r"、" w"、"a”,分别代表读、写、追加。每个模式字符串可包含一个+号,表示同司时读写,或者在写入、追加情况下,如果文件不存在则创建文件。
"r+":表示读/写,不会截断文件。
"w+":表示读/写,但是会先截断文件; 如果文件不存在,会创建文件。
"a+":表示通过追加进行读/写;如果文件不存在,会创建文件。

文件流缓冲

每个文件流都有一个FILE结构体,其中包含一个内部缓冲区。对文件流进行读写需要遍历FILE结构体的内部缓冲区。文件流可以使用三种缓冲方案中的一种。
无缓冲:从非缓冲流中写入或读取的字符将尽快单独传输到文件或从文件中传输。
行缓冲:遇到换行符时,写入行缓冲流的字符以块的形式传输。
全缓冲:写入全缓冲流或从中读取的字符以块大小传输到文件或从文件传输。这是文件流的正常缓冲方案。

代码实践

fread函数:

源代码:
image
读出:
image

fwrite函数:

源代码:
image
文件里的数字是我的学号:
image

控制台:image

C语言代码实现

将文件中的小写字母转换为大写字母

文件内容:image

结果:image

知识点归纳以及自己最有收获的内容

本次学习中最大的收获莫过于是自己调试和解决了文件操作时段错误的问题,在解决问题的过程中我充分掌握了之前不太熟练的各种linux下文件操作的内容,例如新建文件夹、用gcc编译运行从语言文件、用gedit打开C语言文件等等。我也同时感受到了解决问题的快乐,一开始面对各种各样的报错真的非常的难受,也一度想过放弃,但是当我把问题一一解决,最终程序成功运行的那一刻,是非常幸福的,也让我感受到坚持和努力的回报。今后的学习中我也会把这种精神延续下去。

问题与解决思路

image

运行C语言文件出现段错误(核心已转储),网上查询后,发现时为文件分配的空间不足,用ulimit -a查询corefile size大小并改为unlimited

image

编译运行还是出现错误,于是查询core文件路径,发现找不到core路径,也就是说文件执行错误后并没有留下映像文件core,在关闭service apport后找到了core文件但是不在此目录下。

image

此时仍然显示段错误,但没有了核心已转储。接着想用gcc显示权限不够,于是新建一个文件夹和文件,不用sudo(超级用户)创建

image

发现仍然有问题,于是继续查询解决方案,得知可以用gdb来检测错误,于是输入命令gcc -g rdynamic xxx.c 随着gdb ./a.out

image

从gdb的报告中可以看出、得到问题:fwrite的目标文件不存在,检查代码

image

发现fp指向的文件是rb二进制文件,并不是w+,所以不会自动创建文件,因此fp文件指针找不到文件,出现segmentation fault,改为w+后重新编译运行,运行成功!

image

标签:文件,调用,第九章,缓冲,fread,笔记,学习,read,缓冲区
来源: https://www.cnblogs.com/charliecza/p/16678294.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有