如何select开放模式与fopen()?

我有一个关于文件打开模式与fopen()

在我的情况下,我想自由地寻找光标,有时甚至可能超越EOF 。 更重要的是,我也想追加到它而不是截断现有的文件。 我试图以a+模式打开文件; 但是,我不能自由地寻找文件光标。 每次我寻找超出EOF的光标时,新的到达数据将追加到文件的末尾,而不是我指定的位置。 而如果以w+模式打开,现有文件将被截断。 有没有完美的解决这个问题?


更新:

没有明确规定的一点是,文件可能并不总是存在的; 在这种情况下,我必须创build一个新文件。

其实我想处理一个configuration文件。 我不知道这是否是好的做法。 或者我应该先放置一个空的configuration文件。 这样就没有必要在意文件不存在了吗?

以下是代码片段:

 FILE *f = fopen(FILE_PATH, "wb+"); struct record r; if (f) { if (fread((void *)&r, 1, sizeof(struct record), f) { /* File exists, do the normal flow */ } else { if (feof(f)) { /* File is newly created, do some initialization */ } } } else { /* issue a warning */ } 

Solutions Collecting From Web of "如何select开放模式与fopen()?"

你将不得不在两个阶段处理可能不存在的文件,首先假定它在那里,然后处理它的缺席:

 if ((f = fopen(filename, "rb+") == 0) f = fopen(filename, "wb+"); if (f == 0) ...report error... 

"rb+"模式将无法打开一个不存在的文件(但在其他方面表现得如你所愿)。 如果该文件不存在,那么"wb+"将会做你想要的东西(虽然它可能仍然失败,例如,如果文件存在但你没有写入权限)。 你必须希望你没有受到TOCTOU(检查时间,使用时间)攻击的双重尝试。

另一种方法是使用open()系统调用的3参数版本以及相应的标志来打开文件描述符,然后使用fdopen()从文件描述符创建文件流:

 #include <fcntl.h> int fd; if ((fd = open(filename, O_RDRW | O_CREAT, 0644)) >= 0) f = fdopen(fd, "rb+"); 

用标志可以更精确地控制open()

文件模式明确记录为fopen (在Unix / Linux / OS X上试试man 3 fopen )。

r+开放阅读和写作。 流位于文件的开头。

嗨,你可以使用“w +”读写fseek,我写了一个小小的演示程序,首先将数据写入文件,然后使用fseek使每个数据间隔有一个字节,然后读取它:

 #include <stdio.h> #include <unistd.h> #define FILE_PATH "seek_test.txt" #define STEP_SIZE 64 void set_data(FILE* fp) { int i = 0; fseek(fp, 0, SEEK_SET); for ( ; i < 20; ++i) { fprintf(fp, "%d", i); fseek(fp, STEP_SIZE, SEEK_CUR); } } void get_data(FILE* fp) { int i = 0; fseek(fp, 0, SEEK_SET); for ( ; i < 20; ++i) { fscanf(fp, "%d", &i); fprintf(stderr, "Cur Step: %5ld, value = %4d\n", i * STEP_SIZE, i); fseek(fp, STEP_SIZE, SEEK_CUR); } } int main(int argc, char* argv[]) { FILE* fp = fopen(FILE_PATH, "w+"); if (fp == NULL) { printf("fopen Error\n"); exit(0); } set_data(fp); get_data(fp); return 0; } 

===============================结果如下:

Cur步骤:0,值= 0

Cur步骤:64,值= 1

Cur步骤:128,值= 2

Cur步骤:192,值= 3

Cur步骤:256,值= 4

Cur步骤:320,值= 5

Cur步骤:384,值= 6

Cur步骤:448,值= 7

Cur步骤:512,值= 8

Cur步骤:576,值= 9

Cur步骤:640,值= 10

Cur步骤:704,值= 11

Cur步骤:768,值= 12

Cur步骤:832,值= 13

Cur步骤:896,值= 14

Cur步骤:960,值= 15

Cur Step:1024,value = 16

Cur步骤:1088,值= 17

Cur步骤:1152,值= 18

Cur步骤:1216,值= 19

=============================