我正在测试我的程序,以便始终在文件末尾更新数字( num_commit )。此数字用于跟踪文件的写入次数。我正在使用lseek / SEEK_END,但我仍在试图弄清楚它是如何工作的。我编写了以下代码来测试可能性,但 num_commit 似乎被覆盖了。我正在寻找帮助以正确的方式:
#define MAX_PATHNAME_LEN 256
int main()
{
int commit_times = 10;
char pathFile[MAX_PATHNAME_LEN];
sprintf(pathFile, "my_log2.bin");
int filedescriptor = open(pathFile, O_RDWR | O_CREAT, 0777);
int num_segs = 10;
int mods = 200;
const char *segname = "testfil";
char real_segname[128];
strcpy(real_segname, segname); /* in my real program segname is passed into the function */
lseek(filedescriptor, 0, SEEK_END); /* write commit_times always at the end of the file */
write(filedescriptor, &commit_times, sizeof(int));
lseek(filedescriptor, 0, SEEK_SET); /* start writing at the beginning */
write(filedescriptor, &num_segs, sizeof(int));
int name_length = strlen(real_segname);
write(filedescriptor, &name_length, sizeof(int));
write(filedescriptor, real_segname, name_length);
write(filedescriptor, &mods, sizeof(int));
commit_times++; /* increment commit_times */
lseek(filedescriptor, -sizeof(int), SEEK_END); /* then update the commit_times at the end of the file (overwrite the existing number) */
write(filedescriptor, &commit_times, sizeof(int));
close(filedescriptor);
/* now read back the file */
int readfd = open(pathFile, O_RDONLY);
read(readfd, &num_segs, sizeof(int));
read(readfd, &name_length, sizeof(int));
read(readfd, real_segname, name_length);
read(readfd, &mods, sizeof(int));
int num_commit;
read(readfd, &num_commit, sizeof(int));
printf("num_segs=%d, name_length=%d, real_segname=%s, mods=%d, num_commit=%d \n", num_segs, name_length, real_segname, mods, num_commit);
close(readfd);
return 0;
}
这是我的输出,因为你可以看到num_commit被mods值覆盖:
num_segs = 10,name_length = 7,real_segname = testfil,mods = 200,num_commit = 200
答案 0 :(得分:0)
这是我对原始问题的回答。下面的代码将始终写入文件末尾的提交数。每当新条目写入文件时,我确保它将覆盖最后提交的数量并在最后添加新的提交数量。这种方式将增加提交次数,并始终在文件末尾维护只有num_commit 的一个副本。
int main()
{
int name_length;
char pathFile[MAX_PATHNAME_LEN];
sprintf(pathFile, "my_log2.bin");
int filedescriptor = open(pathFile, O_RDWR | O_CREAT, 0777);
int num_segs = 10;
int mods = 200;
const char *segname = "testfil";
char real_segname[128];
strcpy(real_segname, segname); /* in my real program segname is passed into the function */
int i;
for (i = 1; i <= 100; i++)
{
if (i > 1)
{
lseek(filedescriptor, -sizeof(int), SEEK_END); /* overwrite the last num_commit */
}
write(filedescriptor, &num_segs, sizeof(int));
name_length = strlen(real_segname);
write(filedescriptor, &name_length, sizeof(int));
write(filedescriptor, real_segname, name_length);
write(filedescriptor, &mods, sizeof(int));
write(filedescriptor, &i, sizeof(int)); /* number of commits */
}
close(filedescriptor);
/* now read back the file */
int readfd = open(pathFile, O_RDONLY);
lseek(readfd, -sizeof(int), SEEK_END); /* read the number of commit first from the end of the file */
int num_commit;
read(readfd, &num_commit, sizeof(int));
printf("num_commit = %d \n", num_commit);
lseek(readfd, 0, SEEK_SET); /* start reading from the beginning of the file*/
int a, b, m;
char *name;
for (i = 0; i < num_commit; i++)
{
read(readfd, &a, sizeof(int));
read(readfd, &b, sizeof(int));
name = malloc(b);
read(readfd, name, b);
read(readfd, &m, sizeof(int));
printf("commit# = %d, num_segs=%d, name_length=%d, real_segname=%s, mods=%d \n", i+1, a, b, name, m);
free(name);
name = NULL;
}
close(readfd);
return 0;
}
作为替代方案,我还测试了在文件开头维护 num_commit ,这比使用 SEEK_END 更容易/更少思维扭曲:
#define MAX_PATHNAME_LEN 256
int main()
{
int commit_times = 10;
char pathFile[MAX_PATHNAME_LEN];
sprintf(pathFile, "my_log2.bin");
int filedescriptor = open(pathFile, O_RDWR | O_CREAT, 0777);
int num_segs = 10;
int mods = 200;
const char *segname = "testfil";
char real_segname[128];
// strncpy(real_segname, segname, sizeof(real_segname));
strcpy(real_segname, segname);
lseek(filedescriptor, 0, SEEK_SET); /* write commit_times always at the beginning of the file */
write(filedescriptor, &commit_times, sizeof(int));
lseek(filedescriptor, sizeof(int), SEEK_SET); /* start writing after num_commit value */
write(filedescriptor, &num_segs, sizeof(int));
int name_length = strlen(real_segname);
write(filedescriptor, &name_length, sizeof(int));
write(filedescriptor, real_segname, name_length);
write(filedescriptor, &mods, sizeof(int));
commit_times++;
lseek(filedescriptor, 0, SEEK_SET); /* update the commit_times at the beginning of the file */
write(filedescriptor, &commit_times, sizeof(int));
close(filedescriptor);
/* now read back the file */
int readfd = open(pathFile, O_RDONLY);
int num_commit;
read(readfd, &num_commit, sizeof(int));
read(readfd, &num_segs, sizeof(int));
read(readfd, &name_length, sizeof(int));
read(readfd, real_segname, name_length);
read(readfd, &mods, sizeof(int));
printf("num_segs=%d, name_length=%d, real_segname=%s, mods=%d, num_commit=%d \n", num_segs, name_length, real_segname, mods, num_commit);
close(readfd);
return 0;
}