我有以下代码试图读取文本文件,进行备份,并将读取的文件字符串传递给进一步的处理例程。我看到的行为非常出乎意料。
01: rewind(PPLFile);
02: fseek(PPLFile, 0, SEEK_END);
03: unsigned long fsize = ftell(PPLFile);
04: char *string = (char*)calloc(fsize + 1, sizeof(char));
05: rewind(PPLFile);
06: fread(string, sizeof(char), fsize, PPLFile);
07: FILE* PPLBackup;
08: char* fileSuffix = ".backup";
09: char* PPLBackupLocation = (char*)calloc(strlen(basePath) + strlen(fileSuffix) + 1, sizeof(char));
10: strcpy(PPLBackupLocation, basePath);
11: strcat(PPLBackupLocation, fileSuffix);
12: PPLBackup = fopen(PPLBackupLocation, "w");
13: fprintf(PPLBackup, fileContent);
14: fclose(PPLBackup);
15: free(PPLBackupLocation);
文件句柄*PPLFile
先前已使用w+
ora+
标志打开,具体取决于最初编写文件的先前代码中的某些情况。
我认为的概念很简单:
- 将指针移到文件末尾并感知其位置以确定文件大小(以字节为单位)
- 创建字节大小加一的空字符串(用于空终止符)
- 倒带并将整个文件内容读取到字符串中,直到检测到的文件大小
- 创建备份文件名和文件指针
- 将从原始文件读取的整个字符串写入新的备份文件。
- 关闭备份文件并继续处理读取的字符串
有两个令人不安的症状:
- 包含原始文件的 *char 字符串有更多的零(文本文件中有数千个 ~=20MB),因此最后一个非零值可能是从末尾算起的 3000 个字节。看起来比原始文件小。
- 写入备份文件时,生成的文件比原始文件大一点,最后附加了一个看似随机的原始文件额外样本,又是几千字节。
很简单,到底发生了什么?