Ric*_*ral 1 c file-io fwrite fread data-structures
我正在使用fwrite()
并且fread()
第一次将一些数据结构写入磁盘,我对最佳实践和正确的处理方式有几个问题.
我正在写入磁盘(所以我以后可以读回来)是在Graph结构中插入的所有用户配置文件.每个图形顶点都是以下类型:
typedef struct sUserProfile {
char name[NAME_SZ];
char address[ADDRESS_SZ];
int socialNumber;
char password[PASSWORD_SZ];
HashTable *mailbox;
short msgCount;
} UserProfile;
Run Code Online (Sandbox Code Playgroud)
这就是我目前正在将所有配置文件写入磁盘的方式:
void ioWriteNetworkState(SocialNetwork *social) {
Vertex *currPtr = social->usersNetwork->vertices;
UserProfile *user;
FILE *fp = fopen("save/profiles.dat", "w");
if(!fp) {
perror("fopen");
exit(EXIT_FAILURE);
}
fwrite(&(social->usersCount), sizeof(int), 1, fp);
while(currPtr) {
user = (UserProfile*)currPtr->value;
fwrite(&(user->socialNumber), sizeof(int), 1, fp);
fwrite(user->name, sizeof(char)*strlen(user->name), 1, fp);
fwrite(user->address, sizeof(char)*strlen(user->address), 1, fp);
fwrite(user->password, sizeof(char)*strlen(user->password), 1, fp);
fwrite(&(user->msgCount), sizeof(short), 1, fp);
break;
currPtr = currPtr->next;
}
fclose(fp);
}
Run Code Online (Sandbox Code Playgroud)
笔记:
fwrite()
您看到的第一个将写入图表中的总用户数,因此我知道需要读回多少数据.break
是为了测试目的.有成千上万的用户,我还在试验代码.我的问题:
fwrite()
,而不是每个元素写入整个结构.我也避免将指针写入邮箱,因为我不需要保存该指针.那么,这是要走的路吗?fwrite()
对于整个结构,多个而不是全局的?这不慢吗?fread()
但我不知道字符串的大小,因为我曾经strlen()
写过它们.我可以strlen()
在写字符串之前写出输出,但有没有更好的方法没有额外的写入?如果您的程序需要完全可移植,那么您不应该将内存和短路写入磁盘作为内存块:当您尝试在具有不同字长的计算机上读取数据时,数据将被破坏(例如32位 - > 64位)或不同的字节顺序.
对于字符串,您可以先写入长度,也可以在末尾包含终止符.
最好的方法通常是使用基于文本的格式.例如,您可以将每个记录编写为单独的行,其中的字段由制表符或冒号分隔.(作为奖励,您不再需要在文件开头写入记录数量的计数---只需读入记录,直到您到达文件末尾.)
编辑:但如果这是一个你已经给出的课程作业,你可能不需要担心可移植性.'\0'
将字符串中的终止符写入磁盘以分隔它们.读取它时不要担心效率,最慢的位是磁盘访问.
或者甚至fwrite()
整个结构fread()
都重新进入.担心指针?在读取它时用一个安全值覆盖它.不要担心磁盘上浪费的空间(除非你被要求最小化磁盘使用).
如果你确实需要以便携式二进制格式将非负的int写入磁盘,你可以这样做:
所以:
如果您还需要对负数进行编码,则需要在某处为符号保留一点.