stdio的remove()并不总是按时删除
对于一项特定的作业,我正在使用标准 C 下的顺序文件实现一个基本数据存储系统,该系统一次不能加载超过 1 条记录。因此,基本部分是创建一个新文件,其中存储我们对原始记录所做的任何操作的结果。前一个文件被重命名,并以工作名称创建一个新文件。该代码是在 Windows 7 上使用 MinGW 5.1.6 编译的。
问题是,这个特定版本的代码(我的函数周围有几乎相同的版本)并不总是删除旧文件,因此重命名失败因此存储的数据被 fopen() 擦除。
FILE *archivo, *antiguo;
remove("IndiceNecesidades.old"); // This randomly fails to work in time.
rename("IndiceNecesidades.dat", "IndiceNecesidades.old"); // So rename() fails.
antiguo = fopen("IndiceNecesidades.old", "rb");
// But apparently it still gets deleted, since this turns out null (and I never find the .old in my working folder after the program's done).
archivo = fopen("IndiceNecesidades.dat", "wb"); // And here the data gets wiped.
基本上,只要 .old 以前存在,就有可能没有及时删除以便 rename() 成功生效。内部和外部都不可能发生名称冲突。
奇怪的是,它只适用于这个特定的文件。除了名称更改为 Necesidades.dat(发生在 3 个不同的函数中)之外,其他相同的片段都可以正常工作。
// I'm yet to see this snippet fail.
FILE *antiguo, *archivo;
remove("Necesidades.old");
rename("Necesidades.dat", "Necesidades.old");
antiguo = fopen("Necesidades.old", "rb");
archivo = fopen("Necesidades.dat", "wb");
关于为什么会发生这种情况的任何想法,和/或如何确保remove()命令在执行rename()时生效? (我想只要 fopen() 返回一个非空指针,就使用 while 循环来强制再次调用 remove() ,但这听起来像是由于删除请求或其他东西溢出操作系统而导致崩溃。)
For a particular piece of homework, I'm implementing a basic data storage system using sequential files under standard C, which cannot load more than 1 record at a time. So, the basic part is creating a new file where the results of whatever we do with the original records are stored. The previous file's renamed, and a new one under the working name is created. The code's compiled with MinGW 5.1.6 on Windows 7.
Problem is, this particular version of the code (I've got nearly-identical versions of this floating around my functions) doesn't always remove the old file, so the rename fails and hence the stored data gets wiped by the fopen().
FILE *archivo, *antiguo;
remove("IndiceNecesidades.old"); // This randomly fails to work in time.
rename("IndiceNecesidades.dat", "IndiceNecesidades.old"); // So rename() fails.
antiguo = fopen("IndiceNecesidades.old", "rb");
// But apparently it still gets deleted, since this turns out null (and I never find the .old in my working folder after the program's done).
archivo = fopen("IndiceNecesidades.dat", "wb"); // And here the data gets wiped.
Basically, anytime the .old previously exists, there's a chance it's not removed in time for the rename() to take effect successfully. No possible name conflicts both internally and externally.
The weird thing's that it's only with this particular file. Identical snippets except with the name changed to Necesidades.dat (which happen in 3 different functions) work perfectly fine.
// I'm yet to see this snippet fail.
FILE *antiguo, *archivo;
remove("Necesidades.old");
rename("Necesidades.dat", "Necesidades.old");
antiguo = fopen("Necesidades.old", "rb");
archivo = fopen("Necesidades.dat", "wb");
Any ideas on why would this happen, and/or how can I ensure the remove() command has taken effect by the time rename() is executed? (I thought of just using a while loop to force call remove() again so long as fopen() returns a non-null pointer, but that sounds like begging for a crash due to overflowing the OS with delete requests or something.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
所以突然间,在读完 Scott 提到的权限后,我想到了“Permission Denied”并应用了一些 Google。 事实证明这是一个很常见的问题,如果模糊,则错误。
caf 是对的,它在另一段代码中。也就是说,我忘记在用于显示内容的函数中关闭同一个文件。由于我没有追踪那个特定的细节,所以它看起来是随机的。
免责声明:每周的数学作业会占用很少的睡眠时间。 ØØ
So suddenly, after reading Scott's mention of permissions, I thought about "Permission Denied" and applied some Google. Turned out it's a pretty common, if obscure, error.
caf was right, it was in another piece of code. Namely, I had forgotten to fclose that same file in the function meant to show the contents. Since I wasn't tracking that particular detail, it appeared to be random.
Disclaimer: Weekly math assigments make for very little sleeptime. ¬¬
这听起来很奇怪,当你说相同的代码使用不同的文件名可以正常工作时更是如此 - 我强烈怀疑你的代码中其他地方有错误。但是,您应该可以通过重命名要删除的文件来解决此问题:
That sounds quite strange, and even more so when you say that the same code works OK with a different filename - I would strongly suspect a bug elsewhere in your code. However, you should be able to work around it by renaming the file you want to remove:
检查
remove()
函数是否有错误可能是个好主意。man remove
表示该函数成功时返回0
,失败时返回-1
,设置errno
来记录错误。尝试将调用替换为which 应该给出错误消息,说明失败的原因。
此外,似乎没有必要删除
如果出现以下情况,EPERM 将被退回:
所以下一步是检查您是否拥有包含目录的权限
It would probably be a good idea to check the
remove()
function for errors.man remove
says that the function returns0
on success and-1
on failure, settingerrno
to record the error. Try replacing the call withwhich should give an error message saying what failed.
Further, it doesn't appear that the remove is neccessary
EPERM will be returned if:
so the next step would be to check you have permissions on the containing directory