对于c/c++来说,写文件是必不可少的事情。但是如果大家不仔细研究,真的会掉进某些坑里。

在某些紧急情况下,可能要保证数据安全且及时的写到磁盘上,否则就会有丢失的风险。

小文件可能还不那么明显,对于大文件来说,按照平常的方式,可能就出事了。

今天我就带大家来聊一聊这个问题。

读写文件

c语言中文件操作用的是 FILE*, 以及与之相关的打开,读,写,关闭等函数。

对应的是 fopen、fread、fwrite、fclose 等(fgets fputs 等就不在此继续展开了)。

但是在写文件的时候,我们如何保证数据被正确及时的写到磁盘上面了呢?

可能大家会说调用 fflush;很显然如果真的是这样,那今天我也不会写这篇文章了。

那为什么 fflush 不对呢?

缓存

我们可能都知道,文件读写,或者说一般的IO操作都会有缓存。

即磁盘文件被操作系统映射到系统的某个内存中缓存了;我们平常读写是会和缓存打交道。

操作系统根据我们当前操作情况,在缓存与磁盘文件之间进行数据交互。

而对于 fflush 来说,只能保证数据已经被写到了操作系统的文件缓存,不能保证已经写到了磁盘!

只有在 fclose 的时候才能确保缓存数据全部写到磁盘,然后关闭文件。

大家可能会问,那就在 fwrite 写完数据后,直接 fclose 不就行了。

是的,对于小文件来说可能确实如此。

但是对于大文件的时候,可能之前缓存里的数据还没有及时写到磁盘,后面的数据也需要写入;

虽然在 fclose 后会强制将缓存数据写到磁盘,但是可能会需要一点时间,而不巧此时断电了。

解决方案

windows提供的API中,有 CreateFile、ReadFile、WriteFile 和 CloseHandle 来处理IO操作。

其中 CreateFile 有个 dwFlagsAndAttributes 的参数,可以传递不同的属性。

对于我们遇到的问题可以向该参数设置为 FILE_FLAG_NO_BUFFERING 或 FILE_FLAG_WRITE_THROUGH 或者设置成它们相或后的值。

FILE_FLAG_NO_BUFFERING 表示读写文件时,不创建缓存;

FILE_FLAG_WRITE_THROUGH 表示在数据写到缓存后,立刻写入磁盘。

即要写入的文件如下打开即可:

// 打开文件HANDLE hFileDst = ::CreateFileA(dst.toLocal8Bit().data(),                             GENERIC_WRITE,                             0,                             NULL,                             OPEN_ALWAYS,                             /*FILE_FLAG_NO_BUFFERING |*/ FILE_FLAG_WRITE_THROUGH, // 设置flag                             NULL);    if (hFileDst == INVALID_HANDLE_VALUE)    {        CloseHandle(hFileSrc);        return;    }// 数据写入int ret = ::WriteFile(hFileDst, m_dat, dwReadSize, &dwWriteSize, NULL);

需要注意的是 FILE_FLAG_NO_BUFFERING 设置后需要字节对应,文件存取的字节数必须是扇区尺寸的整倍数。

例如,如果扇区尺寸是512字节,程序就可以读或者写512,1024或者2048字节,但不能够是335,981或者7171字节。(这是MSDN上的翻译)

总结

缓存的存在是操作系统为了更好方便我们读写数据,避免因为磁盘的慢速,影响读写操作;

但是如果不清楚其中的原理,可能在特殊情况时,不知道如何处理问题。

当然如果大家没有紧急情况出现,或者对数据写入时间不敏感,可以直接忽略;还是用标准写文件的方式,毕竟更加通用。

如果觉得我写的还不错的话,求赞,求关注哦!(^▽^)

c++ ifstream 文件不结束_C/C++编程笔记:你不知道的windows保存文件的坑相关推荐

  1. c++ ifstream 文件不结束_C++核心编程 第十二节 文件操作

    前言:程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放.通过文件可以将数据持久化. C++中对文件操作需要包含头文件 ,C++中操作文件有不同的文件打开方式,具体见下表所示. 文件打开方 ...

  2. c++ 小游戏_C/C++编程笔记:C语言写推箱子小游戏,大一学习C语言练手项目

    C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...

  3. .net调用c++方法时如何释放c++中分配的内存_C/C++编程笔记:C语言编程知识要点总结!大一C语言知识点(全)...

    一.C语言程序的构成 与C++.Java相比,C语言其实很简单,但却非常重要.因为它是C++.Java的基础.不把C语言基础打扎实,很难成为程序员高手. 1.C语言的结构 先通过一个简单的例子,把C语 ...

  4. UINX环境高级编程笔记 第3章 文件I/O

    UNIX环境高级编程 第三章 文件I/O 3.1 引言 3.2 文件描述符 3.3 函数open和openat 3.4 函数creat 3.5 函数close 3.6 函数lseek 3.7 函数re ...

  5. linux u8 头文件,2019-12-11 转载TCP/IP编程常用C语言头文件

    网络编程的头文件(这里所有的头文件都在/usr/include目录下面) 经常被一些头文件搞大,不知到到哪个头文件去找结构.这里做个总结 ---------------- 版权声明:本文为CSDN博主 ...

  6. status c语言_C/C++编程笔记:C语言编程风格个人总结,初学小白可借鉴

    总结一下我个人的编程风格及这样做的原因吧,其实是为了给实验室写一个统一的C语言编程规范才写的.首先声明,我下面提到的编程规范,是自己给自己定的,不是c语言里面规定的. 一件事情,做成和做好中间可能隔了 ...

  7. linux下编写打印文件的函数,Linux系统编程笔记-文件IO

    本文主要介绍了如下内容: C标准库函数与系统函数的关系 进程控制块 文件描述符 系统调用:open.close.read.write.lseek.fcntl和ioctl 先导概念 C标准库函数与系统函 ...

  8. 保存时自动加分号_CAD自动保存文件扩展名是什么?如何快速恢复自动保存文件?...

    下面是本公众号文章分类目录,点击标题文字可打开分类文章列表: 安装卸载  异常.退出  文件及输入输出  基本操作技巧  各种设置及相关问题  界面和显示相关问题  快捷键  视图设置和调整  图层  ...

  9. 怎么传文件到百度云服务器,别人传文件给我 可是怎么用百度网盘保存文件呢 其实很简单!...

    昨天有不少朋友问老北,百度网盘点下载没有反应,所以老北写一篇关于网盘如何下载文件和上传文件(本文适合新手,高手请飘过吧,手下留情). 生活中或者工作中经常会涉及到传送文件,一般大小的文件都是用微信.Q ...

最新文章

  1. 技术图文:Python 匿名函数 VS. C# Lambda表达式
  2. 饿了么交付中心语言栈转型总结
  3. RocketMQ 很慢?引出了一个未解之谜
  4. flask 知识点总结
  5. Java之杨辉三角的实现
  6. 继续完善掼蛋游戏 其次说说朋友的情况
  7. 如何区分大数据下的三大利器:数据科学家,数据工程师与数据分析师
  8. MySQL的主动优化和被动优化_MySQL“被动”性能优化汇总
  9. Python学习-2.安装IDE
  10. Redhat6.5中搭建Postfix邮件系统
  11. 教你如何正确使用CSDN下载,福利贴,个别方法免积分
  12. Web安全:SQL注入工具
  13. 【SQL注入05】延时盲注实例操作
  14. python爬取西刺网代理IP地址
  15. Oracle 安装 与 卸载 以及 使用 plsqldev
  16. 非计算机专业,如何学习计算机视觉
  17. 文本自动生成研究进展与趋势之总结与展望
  18. MySQL默认字符集设置
  19. 综合案例分析-----使用Ajax实现新闻点评及时更新(ajax在jQuery中的运用学习第十三和十四天)
  20. python编程要懂英语吗_初中毕业没有英语基础能学编程吗?该学C还是Python?

热门文章

  1. 电子设计竞赛电源题(4)-Buck与Boost电路
  2. DIY逗比的时钟,制作资料100%开源!
  3. verilog实现步进电机脉冲分配器(三相六拍)基于Nexys4DDR开发板
  4. 电路常识性概念(2)-电容
  5. ubuntu qt linux 下载文件,Qt ------ linux(ubuntu) 下用 linuxdeployqt 打包发布程序
  6. kafka消息消费有延迟_消息中间件选型分析---从Kafka与RabbitMQ的对比来看全局
  7. mchain r语言_【揭秘】Mchain是长久稳定的项目吗?是不是骗钱的平台?做的人有多少?...
  8. 20220213-CTF MISC-a_good_idea(stegsolve工具的使用)-2017_Dating_in_Singapore
  9. Codeforces.449D.Jzzhu and Numbers(容斥 高维前缀和)
  10. Linux学习之十二-Linux文件属性