fopen中调用_getstream返回NULL导致文件打开失败,ofstream的failbit被设置

问题描述:在导出一个package的时候,调用了一个函数去生出xml文件,在最后用ofstream去保存xml文件的时候,总是失败。然而相同的代码去导出别的package,一切正常。唯一的区别是正常的package较小。


问题分析:在trace代码的时候发现,导致打开文件失败的原因是fopen中调用_getstream返回了NULL,再跟踪到_getstream函数发现,这个函数主要的功能是:试图找到一个没有被使用的stream去打开文件,如果达到512个并且没有找到可用的stream,就会返回NULL。


问题解决:一开始以为是handle使用的太多,导致没有可用的handle,使用task manager勾选上handle去查看,发现并没有想象中的那么多。handle的嫌疑排除。

上网google了很久,也没有准确的答案,没办法,只好把目光重新放回到fopen函数上,在函数入口设置断点,看看都是哪些函数调用了fopen。结果就发现在导出package的时候,有一个计算函数被多次调用,而这个函数被别人加了log,logfile被多次打开,但没有关闭。注掉log代码,测试,一切ok。较小的package的计算较少,log被打开的次数较少,可能没有达到512上限。


最终确定,问题就出在打开的文件太多,而又没有及时关闭。导致stream都被占用了。

fopen_s函数文件路径的确定方式和fopen函数一样,可以使用绝对路径或相对路径。如果使用相对路径,需要注意当前工作目录的设置。 相对路径指的是相对于当前工作目录的路径,当前工作目录是指程序运行时所在的目录。可以使用getcwd函数获取当前工作目录,也可以使用chdir函数改变当前工作目录。 例如,如果要打开位于程序所在目录下的文件filename.txt,可以使用相对路径: ```cpp FILE *file; errno_t err; err = fopen_s(&file, "filename.txt", "r"); if (err != 0) { // 处理文件打开失败的情况 } else { // 处理文件打开成功的情况 // 读取文件内容 char buffer[1024]; while (fgets(buffer, sizeof(buffer), file) != NULL) { // 处理每一行数据 } // 关闭文件 fclose(file); } ``` 如果要打开绝对路径下的文件,可以直接指定文件的路径: ```cpp FILE *file; errno_t err; err = fopen_s(&file, "C:\\path\\to\\filename.txt", "r"); if (err != 0) { // 处理文件打开失败的情况 } else { // 处理文件打开成功的情况 // 读取文件内容 char buffer[1024]; while (fgets(buffer, sizeof(buffer), file) != NULL) { // 处理每一行数据 } // 关闭文件 fclose(file); } ``` 需要注意的是,在Windows系统,路径分隔符为反斜杠(\),而在Linux和Mac OS X等系统,路径分隔符为斜杠(/)。如果要实现跨平台的代码,需要使用路径分隔符常量(如Qt的QDir::separator())来代替硬编码的路径分隔符。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值