windows 为什么 fopen 无法打开存在的文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4690018/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why would fopen fail to open a file that exists?
提问by void
I'm on Windows XP using Visual Studio 6 (yes I know it's old) building/maintaining a C++ DLL. I'm encountered a problem with fopen failing to open an existing file, it always returns NULL.
我在 Windows XP 上使用 Visual Studio 6(是的,我知道它很旧)构建/维护 C++ DLL。我遇到了 fopen 无法打开现有文件的问题,它总是返回 NULL。
I've tried:
我试过了:
- Checking errno and _doserrno by setting both to zero and then checking them again, both remain zero, and thus GetLastError() reports no errors. I know fopen isn't required to set errno when it encounters an error according to a C standard.
- Hardcoding the file path, which are not relative.
- Tried on another developers machine which the same result.
- 通过将 errno 和 _doserrno 设置为零然后再次检查它们来检查 errno 和 _doserrno,它们都保持为零,因此 GetLastError() 不会报告任何错误。我知道 fopen 根据 C 标准遇到错误时不需要设置 errno 。
- 硬编码文件路径,这不是相对的。
- 在另一台开发人员机器上尝试了相同的结果。
The really strange thing is CreateFile works and the file can be read with ReadFile. We believe this works in a release build, however we are also seeing some very odd behaviour in other areas of the application and we're not sure if this is related.
真正奇怪的是 CreateFile 可以工作,并且可以使用 ReadFile 读取文件。我们相信这在发布版本中有效,但是我们也在应用程序的其他领域看到了一些非常奇怪的行为,我们不确定这是否相关。
The code is below, I don't see anything odd it looks quite standard to me. The source file hasn't changed for just under half a year.
代码在下面,我没有看到任何奇怪的东西,它对我来说看起来很标准。源文件在不到半年的时间里没有改变。
HRESULT CDataHandler::LoadFile( CStdString szFilePath )
{
//Code
FILE* pFile;
if ( NULL == ( pFile = fopen( szFilePath.c_str(), "rb") ) )
{
return S_FALSE;
}
//More code
}
回答by void
The Answer:
答案:
I found the cause, too many open file handles cause by some recent updates to the application. These where not code changes though so this bug has been present for a while. I stepped into the fopen function down to a function called _getstream. This attempts to find a stream not in use, the function searches a table of 512 streams Sure enough all 512 where in use and other calls to fopen where failing. I used the handletool from sysinternals to see the number of used handles.
我找到了原因,由于应用程序最近的一些更新导致打开的文件句柄过多。这些地方没有代码改变,所以这个错误已经存在一段时间了。我逐步进入 fopen 函数,直到一个名为 _getstream 的函数。这试图找到一个未使用的流,该函数搜索一个包含 512 个流的表,果然所有 512 个正在使用中,其他调用 fopen 时失败。我使用了sysinternals的handle工具来查看使用的句柄数量。
回答by trojanfoe
Your function has an HRESULT return type (where 0 is good) but you return a boolean (where 0 is bad). That can't be right...
您的函数有一个 HRESULT 返回类型(其中 0 是好的),但您返回的是一个布尔值(其中 0 是坏的)。那不可能是对的...
回答by Will Dean
Assuming you have a reasonable version of VC6, then you have the source code to the CRT, and you can step into the fopen call, and all the way down to the CreateFile call that the CRT will make. (Be prepared for it to be quite a long way down!)
假设您有一个合理的 VC6 版本,那么您就有 CRT 的源代码,您可以进入 fopen 调用,一直到 CRT 将进行的 CreateFile 调用。(准备好它会走很长的路!)
回答by Andriy Tylychko
回答by rashok
You are already having 512 opened files.
您已经有 512 个打开的文件。
We can hold only max 512 opened files in VC application. I am suggesting to close the unnecessary files using fclose
.
我们在 VC 应用程序中最多只能保存 512 个打开的文件。我建议使用fclose
.