是的,您可以fwrite 超过文件末尾(大多数file systems)。如果你不能,fwrite 失败(并给出否定结果)。
当然,这需要之前的fseek 调用成功并更改写入的文件偏移量。你需要检查一下。作为d3L answered,fseek 只能更改fwrite 不会用于附加文件的偏移量。
您可能希望fopen 使用其他模式。不要使用a 附加模式。
例如,您可能在下面有文件tryappend.c(它大约有 509 个字节):
// file tryappend.c, copy it to tryappend.c2 before running
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char* filnam = "tryappend.c2";
FILE *f = fopen(filnam, "a+");
if (!f)
{ perror(filnam); exit(EXIT_FAILURE); };
if (fseek(f, 1024, SEEK_SET)<0)
{ perror("fseek"); exit(EXIT_FAILURE); };
const char str[] = "//// ADDED STUFF\n";
if (fwrite(str, sizeof(str), 1L, f)<0)
{ perror ("fwrite"); exit(EXIT_FAILURE); }
fclose(f);
printf("changed %s\n", filnam);
return 0;
}
并在运行tryappend 可执行文件之前将其复制到tryappend.c2。然后你可以用二进制编辑器或例如检查。 od 在 Linux 上 fwrite-n 的内容已附加在偏移量 510(不是 1024)处,最后你的 tryappend.c2 文件只有 527 个字节(不是 1040 之类的东西)。
如果您坚持直接访问文件,您可以使用较低级别的system calls,例如(在 Linux 或 POSIX 上)open(2)、read(2)、write(2)、lseek(2)、ftruncate(2)、@ 987654332@、close(2) 等...请注意,出于性能原因,您通常应该使用大缓冲区(因此,read 或 write 至少有几千字节的块)。顺便说一句,在 Linux 上,C 标准库(所以<stdio.h> 例程,包括fread、fwrite、fflush,...)正在使用这样的系统调用。
您可能拥有不可搜索的文件。一个很好的例子是在 Linux 上来自/proc 文件系统的一些伪文件(参见proc(5)),例如/proc/self/maps 或popen(3)-ed 文件。
您可以找到比直接访问文件具有更高抽象级别的库,例如sqlite 或 gdbm(我建议使用这些)。当然,您可以使用一些database。另请阅读sparse files。
您应该逐字节精确地定义并记录您的file format(可能使用一些EBNF 表示法)。您可能应该关心文件格式的portability(想想endianness、data alignment、字长等问题),或者提供一种将二进制文件填充或转储为更便携的文本格式的方法。