C\C++文件操作对比
来源:互联网 发布:数据库软件市场份额 编辑:程序博客网 时间:2024/05/20 09:20
开个话题,C\C++文件操作对比
网上多是介绍几种文件操作方式,很少见到比较两种操作的,开个话题有时间研究总结一下:
C与C++文件操作的对比,包括各自特点、效率,C++编程里面究竟应该使用stdio还是stream的文件操作?
搜集的一些材料:
1. http://www.parashift.com/c++-faq-lite/input-output.html
[15.1] Why should I use <iostream> instead of the traditional <cstdio> ?
Increase type safety, reduce errors, allow extensibility, and provide inheritability.
- More type-safe: With
<iostream> , the type of object being I/O'd is known statically by the compiler. In contrast,<cstdio> uses"%" fields to figure out the types dynamically. - Less error prone: With
<iostream> , there are no redundant"%" tokens that have to be consistent with the actual objects being I/O'd. Removing redundancy removes a class of errors. - Extensible: The C++
<iostream> mechanism allows new user-defined types to be I/O'd without breaking existing code. Imagine the chaos if everyone was simultaneously adding new incompatible"%" fields toprintf() andscanf() ?! - Inheritable: The C++
<iostream> mechanism is built from real classes such asstd::ostream andstd::istream . Unlike<cstdio> 'sFILE* , these are real classes and hence inheritable. This means you can have other user-defined things that look and act like streams, yet that do whatever strange and wonderful things you want. You automatically get to use the zillions of lines of I/O code written by users you don't even know, and they don't need to know about your "extended stream" class.
[15.7] Should I end my output lines with std::endl or '\n' ?
Using
This code simply outputs a
void f() { std::cout << ...stuff... << '\n'; }
This code outputs a
void g() { std::cout << ...stuff... << std::endl; }
This code simply flushes the output buffer:
void h() { std::cout << ...stuff... << std::flush; }
Note: all three of the above examples require
[15.16] Why can't I open a file in a different directory such as "..\test.dat" ?
Because
You should use forward slashes in your filenames, even on operating systems that use backslashes (DOS, Windows, OS/2, etc.). For example:
#include <iostream> #include <fstream> int main() { #if 1 std::ifstream file("../test.dat"); // RIGHT! #else std::ifstream file("..\test.dat"); // WRONG! #endif ... }
Remember, the backslash ("\") is used in string literals to create special characters: "\n" is a newline, "\b" is a backspace, and "\t" is a tab,"\a" is an "alert", "\v" is a vertical-tab, etc. Therefore the file name "\version\next\alpha\beta\test.dat" is interpreted as a bunch of very funny characters. To be safe, use "/version/next/alpha/beta/test.dat" instead, even on systems that use a "\" as the directory separator. This is because the library routines on these operating systems handle "/" and "\" interchangeably.
Of course you could use
2. 读取效率
http://www.byvoid.com/blog/fast-readfile/
为确保准确性,我又换到Windows平台上测试了一下。结果如下表:
方法/平台/时间(秒)Linux gccWindows mingwWindows VC2008scanf2.0103.7043.425cin6.38064.00319.208cin取消同步2.0506.00419.616fread0.2900.2410.304read0.2900.398不支持mmap0.250不支持不支持Pascal read2.1604.668从上面可以看出几个问题
- Linux平台上运行程序普遍比Windows上快。
- Windows下VC编译的程序一般运行比MINGW(MINimal Gcc for Windows)快。
- VC对cin取消同步与否不敏感,前后效率相同。反过来MINGW则非常敏感,前后效率相差8倍。
- read本是linux系统函数,MINGW可能采用了某种模拟方式,read比fread更慢。
- Pascal程序运行速度实在令人不敢恭维。
3. 提高速度
(1)内存映射
(2)使用WINAPI
(3)#优化算法 (这才是王道)
http://dev.firnow.com/course/3_program/c++/cppjs/20090403/163891.html
FILE自己维护了一套缓存机制
FILE会使用默认的一个缓存值作为io缓存(4k),或者也可以通过setbuf来设置这个缓存的大小
假 设你fread 1字节 会导致ReadFile 4k,然后fread再将要读取的数据copy到指定的缓冲区中。以后访问只要不过这个边界,就一直从该io缓存中读取,fwrite也是,直到超过io 缓存边界才真正的调用WriteFile。可以调用flush主动强制刷新从而调用WriteFile 或者fclose被动刷新调用WriteFile(这时fclose会阻塞)。
再说一下硬盘的 硬盘的cache由硬盘控制器管理和使用 就像处理器的cache没法直接操作一样 写硬盘的时候会先写入cache 然后硬盘内部会把数据慢慢写入磁盘 这个过程中没有优化 也就是说硬盘驱动按什么顺序写的 写入磁盘就是什么顺序
而实际上 硬盘是个随机访问设备 先写哪个后写哪个无所谓 所以一般在把应用层的io访问转化为底层的io请求后 内核层会做io请求优化排序
假 设一个io队列上目前挂着10个请求 内核层会事先计算每个请求在物理上的位置 然后进行排序 以保证磁头转动一周,尽量让10个请求中的多个在一周内完成,想像一下 最好的情况 10个请求都在一个盘面上 磁头旋转1周 10个请求全部完成 最坏的情况 要转10周 10周的原因是一次只能操作一个磁头 而10个请求可能不幸的在10个盘面上(这时候内核也不会再排序了)
因此让自己的io操作尽可能维持在连续的磁盘空间 且在物理上不跨越盘面 这样效果最好。为此你可能需要硬盘的准确的参数 并精确计算。
缓 存的优势在高强度的io操作会被抵消 因为硬盘的写入速度始终跟不上处理器的请求 cache只能帮助缓冲一下 cache越大 缓冲的时间越长 当cache填满 硬件上ready信号为无效 硬盘驱动不能再写了 只能挂起内核的io队列 这时候上层还在不停的请求 内核层要么继续往io请求队列上挂装请求 要么阻塞发起io的进程 等到cache有空间了 硬件使能ready信号 驱动重新从内河的io请求队列上摘取io请求 再填cache 又满 。。。。 也就是说cache的优势只在一开始的缓存时间上 这个优势对于小的io请求特别有好处 因为能在填满cache之前不会遭到阻塞或挂起
纵上所述 软件上其实做的很有限而且也很累 何必呐 orz。。。。
- C\C++文件操作对比
- C语言和Java中的文件操作对比
- [C/C++]文件操作
- C、C++、Win32、MFC字符串操作对比
- [Object-C]_[C/C++]_[集合操作对比]
- [Object-C]_[C/C++]_[日期时间操作对比]
- C/C++/Window 文件操作
- 【C/C++】C++文件操作
- Windows文件操作【C/C++】
- 【C/C++】文件流操作
- c文件操作
- C文件操作
- C的文件操作
- c语言文件操作
- C的文件操作
- 标准C文件操作
- C#文件操作
- C的文件操作
- MFC_设置对话框背景图片
- 给PHPCMS V9 增加关闭网站功能
- Convert
- log4cplus总结(借鉴网络)
- 同步函数
- C\C++文件操作对比
- 用secureCRT通过SSH连接你的Linux(本文基于Ubuntu 10.04)
- OK或者Cancle按钮
- Vavo:超简洁的手机支架
- iphone--UIWebView中js弹出框修改-
- RHEL6.3下安装was不能启动安装程序的问题
- 自定义interception(拦截器)(一般用不上!)就是继承Interceptor接口(action运行时间例子)
- ubuntu下搭建ftp服务器vsftpd,cuteFTP登录该服务器
- 基于ZigBee 的多点温度采集系统设计与实现