C fopen模式读+写+创建
C fopen mode read+write+create
我要:
- file to be created if it does not exist,
not overwritten if it does
.
- to read and write and
fseek
where ever I want
我找不到有效模式 — "w+"、"rw" "rwb+" "r+b" "w+b" "a+" 还是什么?
表现良好的基本级别“open
”是:
int fd =open("fname", O_RDWR | O_CREAT, 0666);
但我想知道 fopen alternative
。
我尝试的每个模式字母 [w, r, a, +] 组合要么覆盖内容,要么 fseek-fwrite 不写在它应该写的地方。 "a+" 将始终追加,无论 fseek
设置什么...... "rw+" 工作正常,但不会创建不存在的文件......等
更新:阐明为什么例如 "a+" 不是解决方案:
#include <stdio.h>
int main()
{ FILE *fp =fopen("aaa.txt", "a+");
fwrite("aaaaaaaaaaaaaaaaaaa", 1, 10, fp);
fseek(fp, 5, SEEK_SET);
fwrite("AAA", 1, 3, fp);
fclose(fp);
return 0;
}
runned with: $ rm aaa.txt; gcc test.c && ./a.out && cat aaa.txt && echo .
produces wrong result: aaaaaaaaaaAAA.
result should be: aaaaaAAAaa
更新 2:总结...我最终得到的最少功能:
FILE *fopenrwc(char*n) {FILE*f=fopen(n,"a");if(f)fclose(f),f=fopen(n,"r+");return f;}
or:
FILE *fopenrwc(char*n) {return fdopen(open(n,O_RDWR|O_CREAT,0666),"r+");}
没有直接的方法可以通过简单的 fopen
来满足您的要求。恕我直言,您最好的选择是首先使用低级别 open
创建文件,然后使用 fdopen
(如 Jonathan Leffler 所建议的那样)获得 FILE *
然后可以与所有 C 库 IO 函数一起使用:
int fd =open("fname", O_RDWR | O_CREAT, 0666);
FILE *fp = fdopen(fd, "r+");
/* Ok, you can do what you want with fp */
如果您查看 fopen()
的手册页,none 标准开放模式字符串符合您的要求。
如果您使用的机器足够 POSIX 能够使用 open()
, don't underestimate the benefits of fdopen()
这将允许您将 open()
与您显示的选项一起使用,然后创建一个文件流以使用该文件。
请注意 "rw+"
不是有效模式。如果你不走运,它会被视为 r+
.
如果您由于某种原因不能使用 fdopen()
,您最好尝试 r+
,如果失败则使用 w+
;这会打开一个小的 window 漏洞,有人可能会创建一个文件,然后您使用 w+
选项破坏它——或者创建一个符号链接,这样您最终会在您不打算这样做的地方创建一个文件.
这是以前使用 open()
所必需的方式;最初,您调用了 open()
— 在出现 O_CREAT
之前的几天 — 如果失败了,那么您使用了 creat()
instead. That's a long time ago, though — see 'UNIX Programming' in 7th Edition UNIX Programmer's Manual Vol 2.
通常,使用 access()
进行测试没有帮助。它留下了一个 window 的漏洞,因为在 access()
和 open()
(或 fopen()
)的使用之间存在 TOCTOU — 检查时间,使用时间 — 差距。这也是 open()
和 creat()
或两次调用 fopen()
.
的问题
如果您想要更精细的控制,例如 O_EXCL
,或特定的属性,例如 O_DSYNC
或 O_NOCTTY
,甚至控制创建的文件的权限,而不是默认由 umask()
修改,然后 open()
加上 fdopen()
实际上是唯一的方法。
我要:
- file to be created if it does not exist,
not overwritten if it does
.- to read and write and
fseek
where ever I want
我找不到有效模式 — "w+"、"rw" "rwb+" "r+b" "w+b" "a+" 还是什么?
表现良好的基本级别“open
”是:
int fd =open("fname", O_RDWR | O_CREAT, 0666);
但我想知道 fopen alternative
。
我尝试的每个模式字母 [w, r, a, +] 组合要么覆盖内容,要么 fseek-fwrite 不写在它应该写的地方。 "a+" 将始终追加,无论 fseek
设置什么...... "rw+" 工作正常,但不会创建不存在的文件......等
更新:阐明为什么例如 "a+" 不是解决方案:
#include <stdio.h>
int main()
{ FILE *fp =fopen("aaa.txt", "a+");
fwrite("aaaaaaaaaaaaaaaaaaa", 1, 10, fp);
fseek(fp, 5, SEEK_SET);
fwrite("AAA", 1, 3, fp);
fclose(fp);
return 0;
}
runned with: $ rm aaa.txt; gcc test.c && ./a.out && cat aaa.txt && echo .
produces wrong result: aaaaaaaaaaAAA.
result should be: aaaaaAAAaa
更新 2:总结...我最终得到的最少功能:
FILE *fopenrwc(char*n) {FILE*f=fopen(n,"a");if(f)fclose(f),f=fopen(n,"r+");return f;}
or:
FILE *fopenrwc(char*n) {return fdopen(open(n,O_RDWR|O_CREAT,0666),"r+");}
没有直接的方法可以通过简单的 fopen
来满足您的要求。恕我直言,您最好的选择是首先使用低级别 open
创建文件,然后使用 fdopen
(如 Jonathan Leffler 所建议的那样)获得 FILE *
然后可以与所有 C 库 IO 函数一起使用:
int fd =open("fname", O_RDWR | O_CREAT, 0666);
FILE *fp = fdopen(fd, "r+");
/* Ok, you can do what you want with fp */
如果您查看 fopen()
的手册页,none 标准开放模式字符串符合您的要求。
如果您使用的机器足够 POSIX 能够使用 open()
, don't underestimate the benefits of fdopen()
这将允许您将 open()
与您显示的选项一起使用,然后创建一个文件流以使用该文件。
请注意 "rw+"
不是有效模式。如果你不走运,它会被视为 r+
.
如果您由于某种原因不能使用 fdopen()
,您最好尝试 r+
,如果失败则使用 w+
;这会打开一个小的 window 漏洞,有人可能会创建一个文件,然后您使用 w+
选项破坏它——或者创建一个符号链接,这样您最终会在您不打算这样做的地方创建一个文件.
这是以前使用 open()
所必需的方式;最初,您调用了 open()
— 在出现 O_CREAT
之前的几天 — 如果失败了,那么您使用了 creat()
instead. That's a long time ago, though — see 'UNIX Programming' in 7th Edition UNIX Programmer's Manual Vol 2.
通常,使用 access()
进行测试没有帮助。它留下了一个 window 的漏洞,因为在 access()
和 open()
(或 fopen()
)的使用之间存在 TOCTOU — 检查时间,使用时间 — 差距。这也是 open()
和 creat()
或两次调用 fopen()
.
如果您想要更精细的控制,例如 O_EXCL
,或特定的属性,例如 O_DSYNC
或 O_NOCTTY
,甚至控制创建的文件的权限,而不是默认由 umask()
修改,然后 open()
加上 fdopen()
实际上是唯一的方法。