我的任务是更新一个当前从磁盘读取配置文件并填充结构的函数:
static int LoadFromFile(FILE *Stream, ConfigStructure *cs)
{
int tempInt;
...
if ( fscanf( Stream, "Version: %d\n",&tempInt) != 1 )
{
printf("Unable to read version number\n");
return 0;
}
cs->Version = tempInt;
...
}
允许我们绕过将配置写入磁盘并将其直接传递到内存中,大致相当于:
static int LoadFromString(char *Stream, ConfigStructure *cs)
有几点需要注意:
我错过了更好的选择吗?有没有办法创建一个实际上只指向内存而不是磁盘上的位置的FILE *?任何指针,建议或其他帮助都非常感谢。
答案 0 :(得分:3)
如果您无法传递结构并且必须将数据作为字符串传递,那么您应该能够调整函数以从字符串而不是文件中读取。如果函数与您描述的一样复杂,那么转换fscanf
- > sscanf
可能是最简单的方法。
这是使用上面的函数原型的想法。读入整个数据字符串(不处理任何数据字符串)并将其存储在本地缓冲区中。这样,代码可以随意访问数据,因为它可以使用文件并使缓冲区溢出更容易预测和避免。从malloc
一个合理大小的缓冲区开始,将数据复制到其中,并根据需要realloc
自己增加空间。获得整个数据缓冲区的本地副本后,扫描它并提取所需的任何数据。
请注意,如果'\0'
字符是有效输入,这可能会变得棘手。在这种情况下,您必须添加额外的逻辑来测试这是输入字符串的结尾还是零字节(困难取决于数据缓冲区的特定格式)。
答案 1 :(得分:2)
由于您尝试将文件数据保留在内存中,因此您应该可以使用 shared memory 。 POSIX共享内存实际上是映射内存的变体。如有必要,可以使用 mmap() 将共享内存对象映射到进程地址空间。共享内存通常用作IPC机制,但您应该能够根据自己的情况使用它。
以下示例代码使用POSIX共享内存( shm_open() & shm_unlink() )与FILE *
一起编写将文本写入共享内存对象,然后将其读回。
#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#define MAX_LEN 1024
int main(int argc, char ** argv)
{
int fd;
FILE * fp;
char * buf[MAX_LEN];
fd = shm_open("/test", O_CREAT | O_RDWR, 0600);
ftruncate(fd, MAX_LEN);
fp = fdopen(fd, "r+");
fprintf(fp, "Hello_World!\n");
rewind(fp);
fscanf(fp, "%s", buf);
fprintf(stdout, "%s\n", buf);
fclose(fp);
shm_unlink("/test");
return 0;
}
注意:在Linux上使用gcc编译此示例时,我必须将-lrt
传递给链接器。
答案 2 :(得分:1)
使用mkstemp()
创建临时文件。它需要char *
作为参数,并将其用作文件名称的模板。但是,它将返回一个文件描述符。
使用tmpfile()
。它返回FILE *
,但有一些security issues,而且你必须自己复制字符串。
使用mmap()
(Beej's Guide寻求帮助)