我对fopen()
的文件打开模式有疑问。
在我的情况下,我想自由地寻找光标,有时可能甚至超过EOF
。更重要的是,我还想附加到它而不是截断现有文件。我试图以a+
模式打开文件;但是,我不能自由地寻找文件光标。每当我寻找超出EOF
的光标时,新到达数据将附加到文件的末尾,而不是我指定的位置。而如果在w+
模式下打开,则现有文件将被截断。这个问题有完美的解决方案吗?
更新:
未明确指出的一点是该文件可能并不总是存在;在这种情况下,我必须创建一个新文件。
实际上,我想处理一个配置文件。我不知道这样做是否是好的做法。或者我应该首先放置一个空的配置文件。因此没有必要关心案例文件不存在吗?
以下是代码段:
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 */
}
答案 0 :(得分:6)
您必须分两个阶段处理可能不存在的文件,首先假设它存在然后处理它的缺席:
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()
。
答案 1 :(得分:2)
fopen
(在Unix / Linux / OS X上尝试man 3 fopen
)清楚地记录了文件模式。
r+
开放阅读和写作。流位于文件的开头。
答案 2 :(得分:-1)
嗨,您可以使用“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 Step:0,value = 0
Cur Step:64,value = 1
Cur Step:128,value = 2
Cur Step:192,value = 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 Step:768,value = 12
Cur步骤:832,值= 13
Cur步骤:896,值= 14
Cur Step:960,value = 15
Cur Step:1024,value = 16
Cur步骤:1088,值= 17
Cur步骤:1152,值= 18
Cur Step:1216,value = 19
=============================