关于fopen,fprintf,fclose的一个疑难杂症,百思不得其解!请高手指教

czl0325 2012-01-06 07:58:08
代码如下:
我实验,当看到电脑变量hh显示到7391的突然拔掉电脑电源,让他断电,随后重新启动电脑,进去c:\\1.txt的文件看,发现数据之保存到6000多条,也就是少了1000多条的数据,请问代码要怎么改才能使他在断电后依然可以保存数据?
用fputs的方法也没用,用CreateFile的方式来实验也没用。
是不是微软自己本身的问题,希望高手指教。
还有另外在某些笔记本电脑上,一直频繁的if ((pfile=fopen("c:\\1.txt","a"))==NULL)
的话,到了10000万次的时候会出现找不到文件的返回值,打开失败,不知道是什么原因
同样求解。


#include "stdafx.h"
#include <iostream>
#include <windows.h>
using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
FILE *pfile;
DWORD hh=0;
while (true)
{
if ((pfile=fopen("c:\\1.txt","a"))==NULL)
if ((pfile=fopen("c:\\1.txt","w"))==NULL)
return 0;
fprintf(pfile,"%u\n",hh);
fclose(pfile);
//TRACE("hh=%u\n",hh);
cout<<hh<<endl;
hh++;
}
return 0;
}
...全文
2040 48 打赏 收藏 转发到动态 举报
写回复
用AI写文章
48 条回复
切换为时间正序
请发表友善的回复…
发表回复
barbarian110 2012-01-18
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 zhao4zhong1 的回复:]
引用 24 楼 zhao4zhong1 的回复:
不要企图优雅的结束(因为这是不可能办到的)
而要在烂的不能再烂的摊子上也能重整河山!

正解!(^_^)
[/Quote]

又在YY了
lanzhengpeng2 2012-01-11
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 zhyuzhyu 的回复:]

你每次写完后重新读,把读到的值跟写的值比对,一致才继续往下写。效率也许会差些,但肯定不会丢数据。
[/Quote]

没有用的
lfm13720 2012-01-10
  • 打赏
  • 举报
回复
硬盘本身也是有缓冲的,你有什么办法,不用OS也解决不了啊
w20011025 2012-01-10
  • 打赏
  • 举报
回复
使用云存储吧,把数据通过网络传服务器,不怕你断电了
hiho 2012-01-10
  • 打赏
  • 举报
回复
。。。。就不会出现会误导别人的垃圾文件。。。。。。上贴打错字,不好意思
hiho 2012-01-10
  • 打赏
  • 举报
回复
还不如设置一种文件事务机制:选把文件写如一个临时文件中,写完毕再更名过来。这样,就中会出现会误导别人的垃圾文件(不完整的文件)。
楼主这问题也不算是没用的问题,因为在大文件传输中也会出现类似的情况(传输过程断网相当于本机断电),如果留下一个不完整的文件,有时会导致一场灾难。这时候必须采用前述的方法。
丽日湖畔 2012-01-10
  • 打赏
  • 举报
回复
使用云存储吧,把数据通过网络传服务器,不怕你断电了
一叶之舟 2012-01-10
  • 打赏
  • 举报
回复
[Quote=引用 38 楼 weilandeyekong 的回复:]
我在工作中也遇到了这个问题,自己查看MSDN就可以了解到怎么去解决,其实在打开的属性中增加一个“c”就可以了,详细的情况可以参与我的博客http://blog.csdn.net/weilandeyekong/article/details/7176847,这个文章里我有一点分析和相应的解决方案
[/Quote]
这是正解
赵4老师 2012-01-10
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 zhao4zhong1 的回复:]
引用 24 楼 zhao4zhong1 的回复:
不要企图优雅的结束(因为这是不可能办到的)
而要在烂的不能再烂的摊子上也能重整河山!

正解!(^_^)
[/Quote]
理解什么叫“烂的不能再烂的摊子”需要血淋淋的教训啊。
zmkkobe 2012-01-10
  • 打赏
  • 举报
回复
不错的题目学习
赵4老师 2012-01-09
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 qwerasdfmy 的回复:]
引用 24 楼 zhao4zhong1 的回复:

不要企图优雅的结束(因为这是不可能办到的)
而要在烂的不能再烂的摊子上也能重整河山!

这个确实才是王道。你现在只能解决断电问题,那别的怎么办?比如因为别的软件导致的死机、硬盘故障等等,你都要每一个都深入进去么。
[/Quote]
谢谢夸奖!(^_^)
qwerasdfmy 2012-01-09
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 zhao4zhong1 的回复:]

不要企图优雅的结束(因为这是不可能办到的)
而要在烂的不能再烂的摊子上也能重整河山!
[/Quote]
这个确实才是王道。你现在只能解决断电问题,那别的怎么办?比如因为别的软件导致的死机、硬盘故障等等,你都要每一个都深入进去么。
zhangning111 2012-01-09
  • 打赏
  • 举报
回复
这个看样子要到系统级别去想办法,人家微软的系统带写缓存,你光改写入函数看来没用。
赵4老师 2012-01-09
  • 打赏
  • 举报
回复
不要企图优雅的结束(因为这是不可能办到的)
而要在烂的不能再烂的摊子上也能重整河山!
terran_ye 2012-01-09
  • 打赏
  • 举报
回复
用windows的 文件操作api 吧。 writefile, FlushFileBuffers
weilandeyekong 2012-01-09
  • 打赏
  • 举报
回复
我在工作中也遇到了这个问题,自己查看MSDN就可以了解到怎么去解决,其实在打开的属性中增加一个“c”就可以了,详细的情况可以参与我的博客http://blog.csdn.net/weilandeyekong/article/details/7176847,这个文章里我有一点分析和相应的解决方案
zhyuzhyu 2012-01-09
  • 打赏
  • 举报
回复
你每次写完后重新读,把读到的值跟写的值比对,一致才继续往下写。效率也许会差些,但肯定不会丢数据。
feng32tc 2012-01-09
  • 打赏
  • 举报
回复
提供一段更精确的代码。这里限制文件大小为64KB,每次都是使用WriteFile写入64KB。

在虚拟机里执行到输出9498时,直接断电,然后重启,发现里面的字符都是小写的c,(ASCII码是99)。

已经精确到单次IO了哦。


#include <windows.h>
#include <stdio.h>

int main()
{
HANDLE hFile = CreateFile("C:\\1.txt", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_FLAG_NO_BUFFERING, 0);
unsigned int hh=0;
DWORD dwBytes;

unsigned char *block = new unsigned char[65536];

if( hFile == NULL)
return 0;
SetFilePointer(hFile, 65536, 0, FILE_BEGIN);
SetEndOfFile(hFile);

while (true)
{
memset(block, hh % 100, 65536);
SetFilePointer(hFile, 0, 0, FILE_BEGIN);
WriteFile(hFile, block, 65536, &dwBytes, NULL);
printf("%u\n", hh++);
}

CloseHandle(hFile);
return 0;
}
coldfire1 2012-01-09
  • 打赏
  • 举报
回复
fflush吧,每次write完之后,flush一次可以把缓存区的数据写入文件中
赵4老师 2012-01-09
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 zhao4zhong1 的回复:]
不要企图优雅的结束(因为这是不可能办到的)
而要在烂的不能再烂的摊子上也能重整河山!
[/Quote]
正解!(^_^)
加载更多回复(26)

64,676

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧