C++ 文件读写方案选型
严格来说, 有 3 种风格.
- UNIX 底层读写库
- c 语言 stdio 标准库
- iostream 流
一般的工程中, 底层读写库封装程度太低, 需要自己处理缓存和很多通用的异常场景. 不适合.
网络编程中, 缓存会导致很多负面作用, 可以考虑用底层的读写库.
1. 格式化输出对比
1.1 格式化输出的可配置性
iostream 采用 manipulator 来格式化, 格式化信息写死在代码中, 难以实现可配置. -- 软件工程中绝对的硬伤.
stdio 采用的 %d %s 等已经发展成一个 DSL, 并在很多语言中通用. http://en.wikipedia.org/wiki/Printf_format_string#Programming_languages_with_printf
1.2 上下文无关
iostream 中, 通过改变流的状态来实现格式化输出, 而流的状态是全局的. 需要时刻小心,防止影响了后面的代码.
stdio 是上下文无关的.
1.3 缓冲区溢出
stdio 问题在于, 不是类型安全的, 而且存在缓冲区溢出的安全风险. 正确而安全的做法如下
#include <stdio.h> int main()
{
const int max = ;
char name[max]; char fmt[];
sprintf(fmt, "%%%ds", max - );
scanf(fmt, name);
printf("%s\n", name);
}
1.4 类型安全与 64 位兼容性
stdio 的标准库, 需要明确知道待输出数据的类型, 并选择合适的 %d, %ld.
格式化字符串与参数类型不匹配会造成难以发现的 bug.
如果考虑到同时在 32 和 64 位机器上支持正确打印, %d 的选取更加头疼.
《The Linux Programming Interface》的作者建议(3.6.2节)先统一转换为 long 类型再用 "%ld" 来打印;对于某些类型仍然需要特殊处理,比如 off_t 的类型可能是 long long。
http://google-styleguide.googlecode.com/svn/trunk/cppguide.html#64-bit_Portability
printf 无法像打印 int 那样用 printf 来直接打印 自定义对象。
1.5 性能
1. 即使只使用了解释程序的一个功能,也要全部装载。如上面的例子,我们要装载整个包,包括解释浮点数和字符串那部分程序段,无法减少程序的长度。 2. 虽然printf族函数已经优化得很好,但是,它是在运行期间进行解释,如果能在编译期间分析格式字符串里的变量,根据不同的类型调用各自的函数处理,运行会快得多,而且C++编译期间的类型检查会有助于我们发现错误.
在线 ACM/ICPC 判题网站上,如果一个简单的题目发生超时错误,那么把其中 iostream 的输入输出换成 stdio,有时就能过关。
3. 对于C++来说,printf不能被扩展是它最大的缺点。我们不能通过重载函数对它进行扩展,因为重载函数要有不同类型的参数,而printf族函数把类型信息隐藏在可变参数表和格式字符串中。
2. 线程安全
stdio 的函数是线程安全的,
而且 C 语言还提供了 flockfile(3)/funlockfile(3) 之类的函数来明确控制 FILE* 的加锁与解锁。
cout << a << b; 是两次函数调用,相当于 cout.operator<<(a).operator<<(b)。
两次调用中间可能会被打断进行上下文切换,造成输出内容不连续,插入了其他线程打印的字符。
3. 内存泄露
C++ 文件读写方案选型的更多相关文章
- 【Win 10 应用开发】文件读写的三种方案
本文老周就跟伙伴们探讨一下关于文件读写的方法.总得来说嘛,有三种方案可以用,而且每种方案都各有特色,也说不上哪种较好.反正你得记住老祖宗留给我们的大智慧——事无定法,灵活运用者为上. OK,咱们开始吧 ...
- Java中的四套读写方案
一.字节流读写方案 FileInputStream:字节流方式读取文本文件 FileoutputStream:字节流写入硬盘 二.字符流读写方案 FileReader:字符流读取文本 FileWrit ...
- Linux文件读写机制及优化方式
导读 Linux是一个可控性强的,安全高效的操作系统.本文只讨论Linux下文件的读写机制,不涉及不同读取方式如read,fread,cin等的对比,这些读取方式本质上都是调用系统api read,只 ...
- [转载] MySQL高可用方案选型参考
原文: http://imysql.com/2015/09/14/solutions-of-mysql-ha.shtml?hmsr=toutiao.io&utm_medium=toutiao. ...
- c++ 文件读写(转)
C/C++ code //创建一个文本文件并写入信息 //同向屏幕上输出信息一样将信息输出至文件 #include<iomanip.h> #include<fstream.h> ...
- mongoDB 大文件存储方案, JS 支持展示
文件存储 方式分类 传统方式 存储路径 仅存储文件路径, 本质为 字符串 优点: 节省空间 缺点: 不真实存储在数据库, 文件或者数据库发送变动需要修改数据库 存储文件本身 将文件转换成 二进制 存储 ...
- Hadoop小文件存储方案
原文地址:https://www.cnblogs.com/ballwql/p/8944025.html HDFS总体架构 在介绍文件存储方案之前,我觉得有必要先介绍下关于HDFS存储架构方面的一些知识 ...
- C++文件读写 打开方式等比较全
要求:掌握文本文件读写的方法了解二进制文件的读写方法 C++文件流:fstream // 文件流ifstream // 输入文件流ofstream // 输出文件流 //创建一个文本文件并写入信息// ...
- Python(3):文件读写与异常
访问路径: 文件读写必然涉及到文件会放在某个路径下.在python里,可以通过引入os包来实现切换当前访问的路径: # 假设我在 /home/zyq/KiDe/Python/test 文件夹中有一个文 ...
随机推荐
- Pimp_my_Z1
https://github.com/Androguide/Pimp_my_Z1 Pimp_my_Z1-master.zip
- cuda-convnet 卷积神经网络 一般性结构卷积核个数 和 输入输出的关系以及输入输出的个数的说明:
卷积神经网络 一般性结构卷积核个数和 输入输出的关系以及输入输出的个数的说明: 以cifar-10为例: Initialized data layer 'data', producing3072 ou ...
- aspose.cells 模版
aspose.cells 模版 http://www.cnblogs.com/whitewolf/archive/2011/03/21/Aspose_Cells_Template1.html
- 高并发网络编程之epoll详解
select.poll和epoll的区别 在linux没有实现epoll事件驱动机制之前,我们一般选择用select或者poll等IO多路复用的方法来实现并发服务程序.在大数据.高并发.集群等一些名词 ...
- 第2章 数字之魅——斐波那契(Fibonacci)数列
斐波那契(Fibonacci)数列 问题描述 递归算法: package chapter2shuzizhimei.fibonacci; /** * Fibonacci数列递归求解 * @author ...
- Uva120 Stacks of Flapjacks 翻煎饼
水水题.给出煎饼数列, 一次只能让第一个到第i个数列全部反转,要求把数列排序为升序. 算法点破后不值几钱... 只要想办法把最大的煎饼放到最后一个,然后就变成前面那些煎饼的数列的子题目了.递归或循环即 ...
- vsftp安装与配置
配置参考:https://help.aliyun.com/knowledge_detail/5973912.html?spm=5176.776701992.0.0.3X2PB8 553 Could n ...
- Hive的JDBC使用&并把JDBC放置后台运行
使用JDBC访问HIVE: 首先启动hive的JDBC服务. 进入hive的bin目录: 这样启动是启动到前台.如果 要想启动到后台需要用到Linux的相关命令. 我们先把其放到前台看下效果,之后再把 ...
- 24小时学通Linux内核之有关Linux文件系统实现的问题
有时间睡懒觉了,却还是五点多醒了,不过一直躺倒九点多才算起来,昨晚一直在弄飞凌的嵌入式开发板,有些问题没解决,自己电脑系统的问题,虽然Win10发布了,,但我还是好喜欢XP呀,好想回家用用家里的XP来 ...
- android 获取IMEI号
android 获取 imei号码 核心代码: Imei = ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).getDeviceId( ...