C fopen模式读+写+创建

Met*_*tNP 3 c fopen

我想:

\n\n
\n
    \n
  1. 如果文件不存在则创建,not overwritten if it does.
  2. \n
  3. fseek随时随地阅读和写作
  4. \n
\n
\n\n

我找不到有效模式 \xe2\x80\x94 "w+", "rw" "rwb+" "r+b" "w+b" "a+" 或者什么?

\n\n

表现良好的基本级别open是:

\n\n
int fd =open("fname", O_RDWR | O_CREAT, 0666);\n
Run Code Online (Sandbox Code Playgroud)\n\n

但我想知道fopen alternative。\n我尝试的每个模式字母 [w, r, a, +] 组合要么会覆盖内容,要么 fseek-fwrite 不会写在它应该写的地方。“a+”将始终附加,无论fseek设置如何...“rw+”工作正常,但不会创建不存在的文件...等。

\n\n

更新:澄清为什么“a+”不是一个解决方案:

\n\n
#include <stdio.h>\nint main()\n{  FILE *fp =fopen("aaa.txt", "a+");\n   fwrite("aaaaaaaaaaaaaaaaaaa", 1, 10, fp);\n   fseek(fp, 5, SEEK_SET);\n   fwrite("AAA", 1, 3, fp);\n   fclose(fp);\n   return 0;\n}\nrunned with: $ rm aaa.txt; gcc test.c && ./a.out && cat aaa.txt && echo .\nproduces wrong result:  aaaaaaaaaaAAA.\n     result should be:  aaaaaAAAaa\n
Run Code Online (Sandbox Code Playgroud)\n\n

更新2:总结...我最终得到的最小功能:

\n\n
FILE *fopenrwc(char*n) {FILE*f=fopen(n,"a");if(f)fclose(f),f=fopen(n,"r+");return f;}\nor:\nFILE *fopenrwc(char*n) {return fdopen(open(n,O_RDWR|O_CREAT,0666),"r+");}\n
Run Code Online (Sandbox Code Playgroud)\n

Ser*_*sta 5

没有直接的方法可以通过简单的fopen. 恕我直言,您最好的选择是首先使用低级别open来创建文件,然后使用 a fdopen(按照 Jonathan Leffler 的建议)来获取FILE *可以与所有 C 库 IO 函数一起使用的 a :

int fd =open("fname", O_RDWR | O_CREAT, 0666);
FILE *fp = fdopen(fd, "r+");
/* Ok, you can do what you want with fp */
Run Code Online (Sandbox Code Playgroud)


Jon*_*ler 5

如果您查看 的手册页fopen(),就会发现没有一个标准开放模式字符串满足您的要求。

\n\n

如果您在一台足够类似于 POSIX 的计算机上能够使用open(),请不要低估它的好处,fdopen()它允许您使用open()所显示的选项,然后创建一个文件流来使用该文件。

\n\n

请注意,这"rw+"不是有效模式。如果你(不)幸运,它会被视为r+.

\n\n

如果您由于某种原因无法使用fdopen(),您最好尝试一下r+,如果失败,请使用w+; 这会打开一个小漏洞窗口,有人可能会创建一个文件,然后您使用选项w+\xe2\x80\x94 破坏该文件,或者创建一个符号链接,这样您最终会在您不打算这样做的地方创建一个文件。

\n\n

这是过去必须使用的方式open();最初,您open()在存在 \xe2\x80\x94 之前的几天调用了O_CREAT\xe2\x80\x94 ,如果失败,那么您creat()就使用了。那是很久以前的事了,尽管 \xe2\x80\x94 参见第 7 版 UNIX 程序员手册第 2 卷中的“UNIX 编程” 。

\n\n

一般来说,测试access()没有帮助。access()它留下了一个漏洞窗口,因为在和open()(或)的使用之间存在 TOCTOU \xe2\x80\x94 检查时间、使用时间 \xe2\x80\x94 间隙fopen()open()这也是andcreat()或两个调用 to的麻烦所在fopen()

\n\n

如果您想要更精细的控制,例如O_EXCL,或专用属性,例如O_DSYNCO_NOCTTY,甚至控制所创建文件的权限(而不是由 修改的默认权限)umask(),那么open()plusfdopen()实际上是唯一的方法。

\n