FILE* fp;
if( (fp = _fsopen( CW2A(m_strFilePath), "wb",_SH_DENYNO )) !=NULL )
{
int writecount = 0;
while (Number > 0)
{
writecount++;
InternetReadFile(hInternetUrl, Temp, MAXBLOCKSIZE - 1, &Number);
fwrite(Temp, sizeof (char), Number , fp);
if ( WaitForSingleObject ( sParam->ExitEvent , 0 ) !=WAIT_TIMEOUT )
{
fclose( fp );
break;
}
if(sParam->iPos > 100)
{
sParam->iPos = 100;
}
TRACE(L"%s POS = %d\n",sParam->url,sParam->iPos);
}
int bclose = fclose( fp );
}
rename(strFilePath,xxxxx);
此处调用用rename函数,将m_strFilePath重新命名。
有时候rename失败,提示另个程序在调用,无法结束。
我也看过fclose是成功的。
请问这是怎么回事?
26 个解决方案
#1
int bclose = fclose( fp );
rename(strFilePath,xxxxx);放里面!
}
rename(strFilePath,xxxxx);放里面!
}
#2
我使用WIN32 API创建、写文件,关闭后,立即用WIN32 MoveFile()改名,从没遇到问题。
#3
我把rename放到里面还是不行。还有,我这个是多线程在跑,不过开的一个线程就往不同的文件里面写入,这个应该不会影响吧?
#4
“多线程在跑”
要加锁了
要加锁了
#5
加锁是加在一开始写文件地方吗?还是锁在重命名地方?
#6
按说“一个线程就
往不同的文件里面写入”是,
m_strFilePath 应该是不同的,
怎么会 “提示另个程序在调用,无法结束” ?
既然已经“往不同的文件”写,为什么 还要 rename ?
还是“_fsopen( CW2A(m_strFilePath)” 问题,名称应该 是不一样的。
否则 一个线程 打开 后, 另一个 线程 就 不能 打开了。
这句“rename(strFilePath,xxxxx);”都是 固定的 名。
“m_strFilePath” 最好加上 线程 号。
m_strFilePath 应该是不同的,
怎么会 “提示另个程序在调用,无法结束” ?
既然已经“往不同的文件”写,为什么 还要 rename ?
还是“_fsopen( CW2A(m_strFilePath)” 问题,名称应该 是不一样的。
否则 一个线程 打开 后, 另一个 线程 就 不能 打开了。
这句“rename(strFilePath,xxxxx);”都是 固定的 名。
“m_strFilePath” 最好加上 线程 号。
#7
我是在做一个类似下载的东西,重命名是为了区分哪些文件是已经下载完毕,哪些是没有完毕的
#8
我也写过程序:多线程跑,各写各的文件,写完后,关闭文件并重命名;线程之间不需要锁保护。
我觉得是LZ代码哪里有个小逻辑问题。
1)写日志,把open/close/rename记录到日志;
2)程序运行时,不要在资源管理器里打开下载目录,不要点击相关文件;
3)rename失败后,加点代码{ sleep(1000); 重试rename; },看看能否成功。测试版本可以重试3\5次看看。最后rename如果还是失败,用procexp搜索文件,看看哪个进程打开了这个文件。
我觉得是LZ代码哪里有个小逻辑问题。
1)写日志,把open/close/rename记录到日志;
2)程序运行时,不要在资源管理器里打开下载目录,不要点击相关文件;
3)rename失败后,加点代码{ sleep(1000); 重试rename; },看看能否成功。测试版本可以重试3\5次看看。最后rename如果还是失败,用procexp搜索文件,看看哪个进程打开了这个文件。
#9
测试版本也做过重试的动作,还是不能全部重命名成功。只是减少了出错的概率。另外提一下,我单独写多个文件时候没有问题。这个重命名失败,是我在跑其他线程时候,同时在跑写文件的线程才会出现。其他线程主要是做的解压7z文件,然后复制之类的操作。
#10
其它线程与写文件线程之间有什么联系吗?
#11
从流程上看,应该没有联系。操作的是不同路径的文件。
#12
"这个重命名失败,是我在跑其他线程时候,同时在跑写文件的线程才会出现。"==>两类线程一定有点什么联系。用什么API做7z解压?
#13
发的cmd命令,直接解压,没有直接调用api。这个有冲突吗?
#14
还是建议你在删除文件失败时立即用 Process Explorer 工具的 Find -> Find Handle or DLL 看看这个文件被哪些进程打开。
#15
对了,还可以用 sysinternal 的 File Monitor 工具跟踪文件访问情况。
Process Explorer 也是 sysinternal的系列工具之一。
Process Explorer 也是 sysinternal的系列工具之一。
#16
问题找到了。根据程序打出的时间来看,闭关文件句柄时间会比从电脑中看到此文件的最后修改时间要早。关闭了文件句柄,但是电脑还是将缓存的数据写入到文件中去。所以,为什么关闭后,直接重命名会失败,因为当时,电脑还是写文件。
#17
试过了,显示是“non-existent process“。
#18
问题是:
fwrite(Temp, sizeof (char), Number , fp);
这个 fp 不对应 打开时的 fp ?
试试:
fclose( fp );
fp=0;
最好 给 fp
加个 锁。
fwrite(Temp, sizeof (char), Number , fp);
这个 fp 不对应 打开时的 fp ?
试试:
fclose( fp );
fp=0;
最好 给 fp
加个 锁。
#19
这很奇怪!non-existent process一般表示进程退出了,但进程退出后,OS会关闭进程打开的句柄的。
#20
问题找到了。根据程序打出的时间来看,闭关文件句柄时间会比从电脑中看到此文件的最后修改时间要早。关闭了文件句柄,但是电脑还是将缓存的数据写入到文件中去。所以,为什么关闭后,直接重命名会失败,因为当时,电脑还是写文件。
怪了,难道fclose()会异步返回?fclose()返回值呢,成功了吗?
#21
fclose() 返回成功了,返回是0.
#22
问题是:
fwrite(Temp, sizeof (char), Number , fp);
这个 fp 不对应 打开时的 fp ?
试试:
fclose( fp );
fp=0;
最好 给 fp
加个 锁。
这位朋友,程序是多线程下载,如果加锁的话只能一个文件下载,不符合程序设计啊!
#23
还有一个小问题,请教大神们。GetLastError()这个函数,多线程调用时候,返回错误信息会不会错乱?
#24
还有一个小问题,请教大神们。GetLastError()这个函数,多线程调用时候,返回错误信息会不会错乱?
不会。
GetLastError
The GetLastError function retrieves the calling thread's last-error code value. The last-error code is maintained on a per-thread basis. Multiple threads do not overwrite each other's last-error code.
#25
问题已经找到,只是没有找到更好的解决办法,只能不停的重试了。就先关闭了。感谢davidyu720 ,schlafenhamster 支持,结贴了,分不多,请两位见谅。
#26
突然想起来:服务器上装了杀毒软件吗?禁用一下看看?
#1
int bclose = fclose( fp );
rename(strFilePath,xxxxx);放里面!
}
rename(strFilePath,xxxxx);放里面!
}
#2
我使用WIN32 API创建、写文件,关闭后,立即用WIN32 MoveFile()改名,从没遇到问题。
#3
我把rename放到里面还是不行。还有,我这个是多线程在跑,不过开的一个线程就往不同的文件里面写入,这个应该不会影响吧?
#4
“多线程在跑”
要加锁了
要加锁了
#5
加锁是加在一开始写文件地方吗?还是锁在重命名地方?
#6
按说“一个线程就
往不同的文件里面写入”是,
m_strFilePath 应该是不同的,
怎么会 “提示另个程序在调用,无法结束” ?
既然已经“往不同的文件”写,为什么 还要 rename ?
还是“_fsopen( CW2A(m_strFilePath)” 问题,名称应该 是不一样的。
否则 一个线程 打开 后, 另一个 线程 就 不能 打开了。
这句“rename(strFilePath,xxxxx);”都是 固定的 名。
“m_strFilePath” 最好加上 线程 号。
m_strFilePath 应该是不同的,
怎么会 “提示另个程序在调用,无法结束” ?
既然已经“往不同的文件”写,为什么 还要 rename ?
还是“_fsopen( CW2A(m_strFilePath)” 问题,名称应该 是不一样的。
否则 一个线程 打开 后, 另一个 线程 就 不能 打开了。
这句“rename(strFilePath,xxxxx);”都是 固定的 名。
“m_strFilePath” 最好加上 线程 号。
#7
我是在做一个类似下载的东西,重命名是为了区分哪些文件是已经下载完毕,哪些是没有完毕的
#8
我也写过程序:多线程跑,各写各的文件,写完后,关闭文件并重命名;线程之间不需要锁保护。
我觉得是LZ代码哪里有个小逻辑问题。
1)写日志,把open/close/rename记录到日志;
2)程序运行时,不要在资源管理器里打开下载目录,不要点击相关文件;
3)rename失败后,加点代码{ sleep(1000); 重试rename; },看看能否成功。测试版本可以重试3\5次看看。最后rename如果还是失败,用procexp搜索文件,看看哪个进程打开了这个文件。
我觉得是LZ代码哪里有个小逻辑问题。
1)写日志,把open/close/rename记录到日志;
2)程序运行时,不要在资源管理器里打开下载目录,不要点击相关文件;
3)rename失败后,加点代码{ sleep(1000); 重试rename; },看看能否成功。测试版本可以重试3\5次看看。最后rename如果还是失败,用procexp搜索文件,看看哪个进程打开了这个文件。
#9
测试版本也做过重试的动作,还是不能全部重命名成功。只是减少了出错的概率。另外提一下,我单独写多个文件时候没有问题。这个重命名失败,是我在跑其他线程时候,同时在跑写文件的线程才会出现。其他线程主要是做的解压7z文件,然后复制之类的操作。
#10
测试版本也做过重试的动作,还是不能全部重命名成功。只是减少了出错的概率。另外提一下,我单独写多个文件时候没有问题。这个重命名失败,是我在跑其他线程时候,同时在跑写文件的线程才会出现。其他线程主要是做的解压7z文件,然后复制之类的操作。
其它线程与写文件线程之间有什么联系吗?
#11
从流程上看,应该没有联系。操作的是不同路径的文件。
#12
从流程上看,应该没有联系。操作的是不同路径的文件。
"这个重命名失败,是我在跑其他线程时候,同时在跑写文件的线程才会出现。"==>两类线程一定有点什么联系。用什么API做7z解压?
#13
发的cmd命令,直接解压,没有直接调用api。这个有冲突吗?
#14
还是建议你在删除文件失败时立即用 Process Explorer 工具的 Find -> Find Handle or DLL 看看这个文件被哪些进程打开。
#15
对了,还可以用 sysinternal 的 File Monitor 工具跟踪文件访问情况。
Process Explorer 也是 sysinternal的系列工具之一。
Process Explorer 也是 sysinternal的系列工具之一。
#16
问题找到了。根据程序打出的时间来看,闭关文件句柄时间会比从电脑中看到此文件的最后修改时间要早。关闭了文件句柄,但是电脑还是将缓存的数据写入到文件中去。所以,为什么关闭后,直接重命名会失败,因为当时,电脑还是写文件。
#17
还是建议你在删除文件失败时立即用 Process Explorer 工具的 Find -> Find Handle or DLL 看看这个文件被哪些进程打开。
试过了,显示是“non-existent process“。
#18
问题是:
fwrite(Temp, sizeof (char), Number , fp);
这个 fp 不对应 打开时的 fp ?
试试:
fclose( fp );
fp=0;
最好 给 fp
加个 锁。
fwrite(Temp, sizeof (char), Number , fp);
这个 fp 不对应 打开时的 fp ?
试试:
fclose( fp );
fp=0;
最好 给 fp
加个 锁。
#19
还是建议你在删除文件失败时立即用 Process Explorer 工具的 Find -> Find Handle or DLL 看看这个文件被哪些进程打开。
试过了,显示是“non-existent process“。
这很奇怪!non-existent process一般表示进程退出了,但进程退出后,OS会关闭进程打开的句柄的。
#20
问题找到了。根据程序打出的时间来看,闭关文件句柄时间会比从电脑中看到此文件的最后修改时间要早。关闭了文件句柄,但是电脑还是将缓存的数据写入到文件中去。所以,为什么关闭后,直接重命名会失败,因为当时,电脑还是写文件。
怪了,难道fclose()会异步返回?fclose()返回值呢,成功了吗?
#21
fclose() 返回成功了,返回是0.
#22
问题是:
fwrite(Temp, sizeof (char), Number , fp);
这个 fp 不对应 打开时的 fp ?
试试:
fclose( fp );
fp=0;
最好 给 fp
加个 锁。
这位朋友,程序是多线程下载,如果加锁的话只能一个文件下载,不符合程序设计啊!
#23
还有一个小问题,请教大神们。GetLastError()这个函数,多线程调用时候,返回错误信息会不会错乱?
#24
还有一个小问题,请教大神们。GetLastError()这个函数,多线程调用时候,返回错误信息会不会错乱?
不会。
GetLastError
The GetLastError function retrieves the calling thread's last-error code value. The last-error code is maintained on a per-thread basis. Multiple threads do not overwrite each other's last-error code.
#25
问题已经找到,只是没有找到更好的解决办法,只能不停的重试了。就先关闭了。感谢davidyu720 ,schlafenhamster 支持,结贴了,分不多,请两位见谅。
#26
突然想起来:服务器上装了杀毒软件吗?禁用一下看看?