fclose以后,再fopen的问题?

sun007700 2009-06-05 05:07:18
最近写日志文件,发现个问题。
第一次fopen是成功的,并且创建了新文件。
当日志写的很多时,fclose关闭该文件,fopen重新建立个新文件。但是发现这个新文件没有创建。(注:2个文件名字不同)
于是调试代码,发现fclose以后,再fopen返回值是成功的,就是没有看到创建的新文件,真是郁闷之极,不知道有没有遇到此类问题的兄弟,我已经搞了一下午了,还是找不到原因。谢谢^_^
...全文
1004 23 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
sun007700 2009-06-08
  • 打赏
  • 举报
回复
一步一步排查,一开始在子线程里fopen,后来移动到AfxBeginThread之前,依然失败(指没有创建文件,fopen函数却返回成功)。直接移动到button函数最前,成功。然后顺序往下移动,发现当选择文件时,即使用CFileDialog函数时,再fopen就失败。后来用msdn上的CfileDialog的例子
“// szFilters is a text string that includes two file name filters:
// "*.my" for "MyType Files" and "*.*' for "All Files."
char CChildFrame::szFilters[]=
"MyType Files (*.my)|*.my|All Files (*.*)|*.*||";

// Create an Open dialog; the default file name extension is ".my".
CFileDialog fileDlg (TRUE, "my", "*.my",
OFN_FILEMUSTEXIST| OFN_HIDEREADONLY, szFilters, this);

// Display the file dialog. When user clicks OK, fileDlg.DoModal()
// returns IDOK.
if( fileDlg.DoModal ()==IDOK )
{
CString pathName = fileDlg.GetPathName();

// Implement opening and reading file in here.
...
//Change the window's title to the opened file's title.
CString fileName = fileDlg.GetFileTitle ();

SetWindowText(fileName);
}
”再fopen却成功了。于是把自己的Cfiledialog部分替换成msdn样式,也成功了。
但是依然不知道是什么原因,于是把代码又还原为原来的代码,即不用msdn样式。发现再fopen也成了。郁闷之极。。。
我想可能是编译器的问题吧。晕死了。。。。
不过,问题终于解决了。
谢谢各位。^_^
pstrunner 2009-06-08
  • 打赏
  • 举报
回复
file = fopen("Logs\\demo.txt","a");
=======================================
路径是否有问题,你试一试用一个物理路径看看。
sun007700 2009-06-08
  • 打赏
  • 举报
回复
恩,跟踪过,不过现在我把文件名字都变了,直接fopen也是没有创建文件的。
HANDLE hFile;

hFile = CreateFile(TEXT("Logs\\myfile.txt"), // file to create
GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
CREATE_ALWAYS, // overwrite existing
FILE_ATTRIBUTE_NORMAL | // normal file
FILE_FLAG_OVERLAPPED, // asynchronous I/O
NULL); // no attr. template

if (hFile == INVALID_HANDLE_VALUE)
{
printf("Could not open file (error %d)\n", GetLastError());
return 0;
}
CStdioFile stdioFile;
if(!stdioFile.Open("Logs\\demo2.txt",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite) )
{
// AfxMessageBox("打开end.txt失败!");
return FALSE;
}
CString str = "";
FILE *file;
file = fopen("Logs\\demo.txt","a");
这段代码放在我的程序的子线程里,一个文件也创建不了,但是每个函数的返回值却都是成功的。而把这段代码放在一个button按钮函数里却是都成功的,文件都创建了 。
这段代码放在我写的一个测试程序的线程里,却是成功的,真是见鬼了感觉。。。。
现在不知道到底是怎么一回事了,不知道是哪里冲突了还是怎么的。对了, 我用的是vs2003编译器。。
ltc_mouse 2009-06-08
  • 打赏
  • 举报
回复
m_Time.Format("Logs\\UpgradeLOG%Y_%m_%d_%H_%M.log")
--------------------------
这个文件的文件名是分钟的,如果分钟没有变化,很可能只是打开了之前的文件;有跟踪过,这个文件名的情况吗?
sun007700 2009-06-08
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 ltc_mouse 的回复:]
fopen,fclose系列函数似乎不是线程安全的。Windows下的话,可以考虑CreateFile~
你是怎么加锁的呢?所有用fopen,fclose,fread,fwrite,fseek都加锁了吗?
[/Quote]
EnterCriticalSection(&CRITICAL_Log);
CString tmstr,logstr;

if(m_LogFile != NULL)
{
m_Time=CTime::GetCurrentTime();
tmstr=m_Time.Format("<%Y-%m-%d %H:%M:%S>");
logstr.Format("%s-- %s\r\n",tmstr,LogMess);
fwrite(logstr,1,logstr.GetLength(),m_LogFile);
fflush(m_LogFile);
m_iLogLines++;
}

if(m_iLogLines>=4)//最大5000行999
{
m_iLogLines=0;
if(m_LogFile != NULL)
fclose(m_LogFile);
m_LogFile = NULL;
//m_Time=CTime::GetCurrentTime();
if((m_LogFile=fopen(m_Time.Format("Logs\\UpgradeLOG%Y_%m_%d_%H_%M.log"),"a")) == NULL)
{
TRACE("fopen error!\r\n");
}
int nErr = GetLastError();
TRACE("nErr = %d\r\n", nErr);
}

LeaveCriticalSection(&CRITICAL_Log);
该加锁的都加了,就这一个函数。
我刚才在测试程序里也用了线程,发现是可以fopen以后是可以创建文件的,但是我的这个程序里用fopen在线程里就创建不了文件,虽然返回值是成功的。
并且我用了刚才这位兄弟的createfile函数在我的线程里也创建不了文件。郁闷。但是在测试程序的线程里是成功的。
我现在怀疑是不是我的程序那里和创建文件有冲突在线程里的时候,郁闷之极~~
ritawwl 2009-06-08
  • 打赏
  • 举报
回复
ltc_mouse 2009-06-08
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 sun007700 的回复:]
上午写了个测试程序。发现fclose以后fopen是成功的,但是在我的程序里却是失败的,后来把测试程序的代码移到我的程序里(一个button按钮下),也是成功的。但是移到出问题的地方,却是失败的。发现失败的地方是在子线程中使用的,是不是在子线程里不可以操作fopen呢,并且我加了互斥的呀,郁闷。
不知道有哪位兄弟遇到过此种情况,解释下~
[/Quote]
fopen,fclose系列函数似乎不是线程安全的。Windows下的话,可以考虑CreateFile~
你是怎么加锁的呢?所有用fopen,fclose,fread,fwrite,fseek都加锁了吗?
sun007700 2009-06-08
  • 打赏
  • 举报
回复
上午写了个测试程序。发现fclose以后fopen是成功的,但是在我的程序里却是失败的,后来把测试程序的代码移到我的程序里(一个button按钮下),也是成功的。但是移到出问题的地方,却是失败的。发现失败的地方是在子线程中使用的,是不是在子线程里不可以操作fopen呢,并且我加了互斥的呀,郁闷。
不知道有哪位兄弟遇到过此种情况,解释下~
pathuang68 2009-06-05
  • 打赏
  • 举报
回复
goodname 2009-06-05
  • 打赏
  • 举报
回复
第二次创建成功,
一般来说你要是依照资源管理器来查看的话,是不能立刻看到文件的。
因为文件系统都是带缓冲的,资源管理器也不是立刻刷新的。

你可以多刷新几次文件列表,过会应该就可以看到。

猜测的,以前我们的系统也有日志模块,就是如上我所说。
「已注销」 2009-06-05
  • 打赏
  • 举报
回复
加Sleep(1000)试试。
sun007700 2009-06-05
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 shenxianqiang 的回复:]
参数的问题吧,"a"是append,打开时文件必须存在,否则出错,用"w"方式试试看呢?
[/Quote]

"a"
Opens for writing at the end of the file (appending) without removing the EOF marker before writing new data to the file; creates the file first if it doesn't exist.
如果文件不存在,会创建的,"w"方式我试过了,不行的。

现在纳闷的就是为什么第一次执行fopen是成功的,第二次(fclose以后)以同样的方式fopen(函数返回成功),却创建不了文件,郁闷~~
sun007700 2009-06-05
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 cxz1985 的回复:]
引用 7 楼 Loaden 的回复:
使用GetTickCount()函数吧,精确到ms


或者是把log的名字改一下 。。。毕竟你这个精确到分钟的话总是会有问题的。。
[/Quote]

名字改了也不行,晕死,感觉fclose以后,马上执行fopen函数好像就不行似的!~~
shenxianqiang 2009-06-05
  • 打赏
  • 举报
回复
参数的问题吧,"a"是append,打开时文件必须存在,否则出错,用"w"方式试试看呢?
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 Loaden 的回复:]
使用GetTickCount()函数吧,精确到ms
[/Quote]
或者是把log的名字改一下 。。。毕竟你这个精确到分钟的话总是会有问题的。。
sun007700 2009-06-05
  • 打赏
  • 举报
回复
文件名是不同的,我跟进了CTime的Format函数看了的。。。

//m_Time=CTime::GetCurrentTime(); 注释掉,是因为前边已经调用过一次了,不好意思,可能您误解了。
「已注销」 2009-06-05
  • 打赏
  • 举报
回复
使用GetTickCount()函数吧,精确到ms
goodname 2009-06-05
  • 打赏
  • 举报
回复
而且windows的CTime::GetCurrentTime()取得的时间也并精确,
你可以在你得程序中连续的取,你会看到很多是一样的m_Time
goodname 2009-06-05
  • 打赏
  • 举报
回复
可能是速度太快了,导致的两个文件名相同了

下面的fopen创建成功并不是新文件,而是把旧的给打开了
sun007700 2009-06-05
  • 打赏
  • 举报
回复
第一次创建是成功的,第二次fopen成功,就是看不到文件。不知道是不是文件隐藏了,郁闷。。
加载更多回复(3)

70,029

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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