我想:
- 如果文件不存在,则创建
not overwritten if it does
。- 读写,
醇>fseek
我想要的地方
我无法找到有效的模式 - " w +"," rw" " RWB +" " R + B" " W + B" " +"或者什么?
基本级' open
'表现良好的是:
int fd =open("fname", O_RDWR | O_CREAT, 0666);
但我想知道fopen alternative
。
我试过的每个模式字母[w,r,a,+]组合都会覆盖内容,或者fseek-fwrite不会写入应该的位置。 " +"无论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
Update2:摘要...我最终得到的最小功能:
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+");}
答案 0 :(得分:3)
使用简单的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 */
答案 1 :(得分:2)
如果您查看fopen()
的手册页,则所有标准开放模式字符串都不符合您的要求。
如果你在类似POSIX的机器上使用open()
,请不要低估fdopen()
的好处,这样可以让open()
使用"rw+"
您显示的选项,然后创建文件流以使用该文件。
请注意,r+
不是有效模式。如果您(非)幸运,则将其视为fdopen()
。
如果由于某种原因无法使用r+
,则最好尝试w+
,如果使用w+
失败,这会打开一个小漏洞窗口,有人可能会创建一个文件然后使用open()
选项进行破坏 - 或者创建一个符号链接,这样您最终就会创建一个您不打算这样做的文件。
这是以前使用open()
所必需的方式;最初,您在O_CREAT
之前的几天内调用了access()
- 如果失败了,那么您使用的是creat()
。这是很久以前的事了 - 请参阅7th Edition UNIX Programmer's Manual Vol 2中的“UNIX编程”。
通常,使用access()
进行测试无济于事。它留下了一个漏洞窗口,因为有一个TOCTOU - 检查时间,使用时间 - 使用open()
和fopen()
(或open()
)之间的差距。这也是creat()
和fopen()
或两次调用O_EXCL
的问题。
如果您想要更精细的控件(例如O_DSYNC
)或专用属性(例如O_NOCTTY
或open()
),或者甚至可以控制创建文件的权限(默认值除外)由umask()
修改,然后fdopen()
加上index
实际上是唯一的出路。