Linux 系统编程2:缓冲I/O(标准I/O)

前言:上一章介绍了LINUX系统调用的一些文件I/O函数,本章将继续学习C库中的标准I/O函数。

文件指针:标准I/O并不是直接操作文件描述符,他们有自己的唯一标识符---文件指针去操作.文件指针和文件描述符是一一映射的关系

1.打开文件

   1).  通过fopen()打开,返回文件所映射的文件指针。

#include <stdio.h>FILE* fopen(const char* path,const char* mode);

和open()函数类似,有文件路径和打开方式。mode有如下几种:
r:只读模式打开文件,流指针指向文件开始。

r+:可读模式打开,流指针指向文件开始。

w:只写模式打开,往里写东西,若文件存在,文件内容被清空,文件不存在则创建文件,流指针指向文件开始。

w+:可写模式打开文件,规则情况同w

a:追加模式打开文件,文件不存在则创建文件。流指针指向文件的末尾,所有人写的文件都是追加到文件的末尾。

FILE* stream;
stream=fopen("/etc/manifest","r");
//只读模式打开

2).可以通过函数fdopen()把一个已经打开的文件描述符(open()或网络编程函数创建的可以进行读写的文件描述符)转化为流。

#include <stdio.h>
FILE* fdopen(int fd.const char* mode);

  但要注意的是:fdopen()的可能模式和fopen()的可能模式相同,而且必须和最初打开文件描述符的模式相匹配。fdopen()里指定的写模式不会清空原文件内容。

注意文件描述符并没有被复制,而只是关联了一个新的流,关闭了流也会关闭文件描述符。如下例子。

FILE* stream;
int fd;fd=open("/home/user/1.txt",O_RDONLY);
if(fd==-1){
........
}stream=fdopen(fd,"r");
if(!stream)/*error*/

3).关闭流

#include <stdio.h>int fclose(FILE* stream);int fcloseall(void);//此函数会关闭所有当前进程的输入输出流,包括标准输入和标准输出。

2.从流中读取数据:

1). 一般情况下是每次只读取一个字符。函数fgetc()可以每次从流中读取单个字符;

#include <stdio.h>int fgetc(FILE* stream);

注意上述函数强转为unsigned int类 不论读取什么类型的字符。比如char类,想输出强转回去。

int c;
c=fgetc(stream);printf("c=%c\n",(char)c);

2).每次读取一行的数据,函数fgets()

#include <stdio.h>
char* fgets(char* str,int size,FILE* stream);

该函数从stream中读取size-1个字节,保存在str中,读取最后一个字节后,缓冲区会写入'\0',读到EOF或换行符时,读结束,换行符'\n'写入str中。 读取成功后返回str,失败是NULL。

char buf[MAX_SIZE];if(!fgets(buf,MAX_SIZE,stream)
/*error*/

3).读取二进制文件。

#include <stdio.h>size_t fread(void* buf,size_t size,size_t nr,FILE* stream);从流stream中,读取nr项数据,每项size个字节,存放在buf中 返回实际读到的项数,文件指针向前移动读到的字节数。

3:从流中写数据:

1).写入单个字符:

#include <stdio.h>
int fgetc(int c,FILE* stream);文件指针stream必须以写打开,会将c所表示的字节强转为unsigned char类存入流中,成功返回c,失败返回EOF。

2).写入一行;

#include <stdio.h>int fputs(const char* str,FILE* STREAM)将指向str的所有字符串全部都写入stream中,不会写入结束标识符,成功返回非负数

3).写入二进制数据。

#include <stdio.h>size_t fwrite(void* buf,size_t size,size_t nr,FILE* stream);会把buf中的nr项,每项size长度的文件将数据写入stream,文件指针向前移动写入字节数

例子:

#include <stdio.h>
#include <iostream>
int main(){FILE* in ,*out;struct pirate{char mame[100];long booty;int beard_len;}p,blackbeard{"Edward Teach",950,48};out=fopen("hello.txt","w");if(!out){perror("fopen");exit(1);}if(!fwrite(&blackbeard,sizeof(struct pirate),1,out)){perror("fwrite");exit(1);}fclose(out);in=fopen("hello.txt","r");if(!in){perror("fopen");exit(1);}if(!fread(&p,sizeof(struct pirate),1,in)){perror("fread");exit(1);}fclose(in);std::cout<<p.beard_len<<p.booty<<p.mame<<std::endl;return 0;}

4.Flush(刷新输出流)

#include <stdio.h>int fflush(FILE* stream);

调用该函数时,stream指向的流所有未使用的数据会被flush到内核中。

本节中所以调用所需要的缓冲区都是有C库函数来维持的,其处在用户空间,而不是内核空间。这些调用的性能提升空间来自于用户空间,而不是内核,不是系统调用。fflush的作用是,将用户没写的数据加入内核缓冲区中,类似于直接调用write函数。但其不能保证数据最终被写入磁盘中,需要先调用fflush()后立刻调用fsync().先确保被写入内核当中,然后保证内核数据写入磁盘中。

这里提一点:标准I/O其实性能比较低,当读数据时,标准I/O会向内核发起read()系统调用,将数据拷贝在标准I/O缓存中,然后通过标准I/O的fget请求,又会拷贝一次到指定缓冲区。写输入也是如此,这样就拷贝了两次。有性能损耗。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/50635.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JDK9 module 新特性

JDK9 module 新特性 模块结构 模块 src 包 代码.java module-info.java requires/exports requires代表需要某个模块、exports代表暴露出哪些包里的类&#xff1b; ● 创建hello.module module hello.module {exports com.adi; }public class HelloProvider {public vo…

Open3D 获取点云中指定高度区域的所有点

目录 一、概述 1.1实现步骤 1.2应用 二、代码实现 1.1关键函数 1.2完整代码 三、实现效果 3.1原始点云 3.2处理后点云 Open3D点云算法汇总及实战案例汇总的目录地址&#xff1a; Open3D点云算法与点云深度学习案例汇总&#xff08;长期更新&#xff09;-CSDN博客 一、…

CentOS 7.x 的 YUM 仓库问题

背景 CentOS Linux 7 的生命周期&#xff08;EOL&#xff09;已经于 2024 年 6 月 30 日终止这意味着 CentOS 7.x 的官方镜像站点将不再提供服务&#xff0c;导致在使用 yum 安装或更新程序时可能会遇到 错误。本文将介绍如何解决这一问题&#xff0c;使得你可以继续在 CentOS…

【vim】ubuntu20-server 安装配置 vim 最新最详细

在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。【vim】ubuntu20-server 安装配置 vim 最新最详细 开发环境一、vim github二、安装必…

Elasticsearch 使用误区之三——分片设置不合理

Elasticsearch 是一个强大的搜索和分析引擎&#xff0c;它通过将数据分散到多个节点的分片中来进行分布式处理。 本文将探讨分片大小和策略的概念&#xff0c;以优化 Elasticsearch 的性能并防止过度分片或分片过大等问题。 先看个分片设置不合理的真实企业案例&#xff1a; 10…

DML数据库的数据类型

DML 用于改变数据表中的数据的操作语言。 包括INSERT&#xff08;将数据插入到数据表中&#xff09;,UPDATE&#xff08;更新表中已经存在的数据&#xff09;,DELETE&#xff08;删除表中已经存在的数据&#xff09; INSERT 用法 INSERT INTO 表名&#xff08;字段1&#x…

Qt实现输出日志到指定文件

开发平台 &#xff1a; Qt Creator 语言&#xff1a; C 需求&#xff1a; 获取日志信息&#xff0c;写入指定文件日志7天后过期保护写入日志进程 前置操作&#xff1a; 1.在CMakeLists.txt中添加如下代码 # 添加预处理&#xff0c;防止在release模式下&#xff0c;输出的…

CSS:position属性

一、属性值 1.1 fixed 固定位置的元素&#xff0c;相对于浏览器窗口进行定位。 元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。 网站中的固定 header 和 footer 就是用固定定位来实现的&#xff1b; header效果图 footer效果图 1.2 absol…

浏览器自动化测试工具selenium——爬虫操作记录

selenium——是一款web自动化测试框架&#xff0c;其能模拟正常的用户操作&#xff0c;比如点击。但selenium并不是浏览器&#xff0c;没有执行js和解析html/css的能力&#xff0c;因此selenium需要和浏览器配合使用。 因为selenium可以模仿用户行为&#xff0c;因此selenium也…

Linux系统安装Cobol语言及IBM大型机模拟软件Hercules

COBOL&#xff08;Common Business-Oriented Language&#xff09;起源于50年代中期&#xff0c;是一种面向过程的高级程序设计语言&#xff0c;主要用于商业和数据处理领域。经过不断发展和标准化&#xff0c;已成为国际上应用最广泛的商业编程语言之一&#xff0c;在某red书上…

Windows Server搭建局域网NTP时间服务器与客户端通实现

1.服务器环境&#xff1a; win11更改注册表 winR输入regedit win11更改注册表 winR输入regedit 2.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Config&#xff0c;找到Config目录&#xff0c;双击Config目录下的AnnounceFlags&#xff0c;设为5。 3.HKEY_L…

Nginx 配置与优化:常见问题全面解析

文章目录 Nginx 配置与优化:常见问题全面解析一、Nginx 安装与配置问题1.1 Nginx 安装失败问题描述解决方法1.2 Nginx 配置文件语法错误问题描述解决方法二、Nginx 服务启动与停止问题2.1 Nginx 无法启动问题描述解决方法2.2 Nginx 服务无法停止问题描述解决方法三、Nginx 性能…

Http 和 Https 的区别(图文详解)

在现代网络通信中&#xff0c;保护数据的安全性和用户的隐私是至关重要的。HTTP&#xff08;Hypertext Transfer Protocol&#xff09;和 HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;是两种常见的网络通信协议&#xff0c;但它们在数据保护方面的能力存在…

snkemake入门

一、背景介绍 snakemake是一种用于自动化流程的开源工具&#xff0c;是一款基于python3的软件。在生物信息学、高通量测序数据分析、大规模数据处理等领域非常流行。 snakemake的官网&#xff1a;Snakemake | Snakemake 8.16.0 documentationhttps://snakemake.readthedocs.i…

Android SurfaceFlinger——GraphicBuffer内存申请(三十)

在上一篇文章中介绍 GraphicBuffer 初始化的 initWithSize() 函数中,有两个核心方法,GraphicBufferAllocator.allocate 和 GraphicBufferMapper. getTransportSize,这里我们就来看一下 allocate() 函数是如何实现内存申请的。 一、函数介绍 在Android的图形子系统中,Graph…

自监督学习概述(Self-Supervised Learning,SSL)

自监督学习&#xff08;Self-Supervised Learning&#xff0c;SSL&#xff09;是一种机器学习方法&#xff0c;旨在利用未标记数据进行训练。这种方法通过从数据本身生成伪标签&#xff0c;来创建监督信号&#xff0c;使得模型能够学习有效的数据表示。自监督学习在深度学习领域…

C++ | Leetcode C++题解之第283题移动零

题目&#xff1a; 题解&#xff1a; class Solution { public:void moveZeroes(vector<int>& nums) {int n nums.size(), left 0, right 0;while (right < n) {if (nums[right]) {swap(nums[left], nums[right]);left;}right;}} };

第一周第三天任务

入职了新公司&#xff0c;电脑限制了公网访问&#xff0c;为了补上打卡进度&#xff0c;后面的打卡内容纯手敲文本&#xff0c;没有图片&#xff0c;不便之处请谅解&#xff0c;如果错误&#xff0c;请帮忙指正&#xff0c;谢谢。 11 使用docker-compose 使用一个工具&#x…

多通道音频解决方案

多通道音频解决方案在现代音频应用中具有广泛的应用&#xff0c;特别是在需要处理多个音频信号、实现复杂声音场景和提升用户体验的场合。比如音乐录制和影视和游戏音效设计等等。 音乐录制与制作音乐录制 需求: 音乐录制工作室需要能够同时录制和处理多个音轨&#xff0c;以便…

百度地图埋点动态插入到页面不生效, 定位发现是 document.write 缘故,不能异步引入该埋点 js

背景: 为提高页面加载速度, 根据地址的不同加载不同的 script (Vue 项目, 一份代码放到多个地址, 根据地址不同显示不同登录页), 结果引用的百度地图 api 失效 定位: 发现埋点 js 引入成功, 该 js 生成的内容是 document.write 再引入 js , css 文件, 这些文件没有加载出来 …