读取时将额外的字符添加到文件末尾

Extra char's added to end of file when read

我正在将一个文件从 linux 复制到我们的文件系统,我们已经成功地完成了,但是当文件被打印出来时,文件末尾有额外的字符。我们认为它与内存分配有关,但我们看不到如何修复它。谢谢您的帮助!

ACTUAL EOF:∴但没有 TM 可能决定 H,因此 M_o 不可能存在。}�0E�

正确的EOF:∴但是没有TM可以决定H,所以M_o不可能存在。

void copyToFS(char *filePath, int currentDirectoryID)
{
    printf("Enter file path: ");
    scanf("%s",filePath);
    int node = assignNode(filePath, 0, currentDirectoryID);
    long int fileSize = getFileSize(filePath);

    FILE *file  = fopen(filePath, "r");

    printf("\nSize of : %ld", fileSize);

    char fileBuffer[fileSize];

    if (file != NULL) {
        fseek(file, 0, SEEK_SET);
        fread(fileBuffer, fileSize, 1, file);

    } else {
        printf("Could not open file :(");
    }

    fclose(file);

    printf("\n%s", fileBuffer);

    assignBlocks(fileBuffer, node, fileSize/512);
}

这里有几个问题。让我们从与您的问题有关的问题开始:

首先,fileBuffer包含文件的内容。没关系,除了 printf()%s 需要一个 C 字符串,而不是文件的内容。区别在于 C 字符串以空字节 [=17=].

结尾

然后,您假设文件仅包含文本。如果文件是二进制文件,特别是如果它在某处包含空字节,则您的打印将无法工作。

如何解决这两个问题:使用不需要空字节的 fwrite():替换

printf("\n%s", fileBuffer);

fwrite("\n", sizeof("\n"), 1, STDOUT);
fwrite(fileBuffer, fileSize, 1, STDOUT);

接下来是文件大小的假设。如果文件大小为 16MB,你将尝试在堆栈上分配 16MB 内存,这会使你的程序崩溃。

如何解决:要么断言假设(if (fileSize > SOMETHING) return; 或类似的东西),要么用 malloc().

动态分配 fileBuffer

接下来,您没有处理来自 fread() 的错误。如果失败,fread() 将 return 0.

如何修复:防弹方法是使用如下循环:

while (!feof(file)) {
    fread(fileBuffer, fileSize, 1, file);
}

但是,如果您的文件很大,fread() 可能只读取其中的一部分,您需要:

n = 0;
while (!feof(file)) {
    r = fread(fileBuffer + n, 1, fileSize, file);
    n += r;
}

注意当你写文件的时候(在assignBlocks(),我假设),如果你使用fwrite(),你也需要一个类似于fread()的循环。

最后,我猜测 fileSize/512 应该是文件中的扇区数,但是如果文件是 1500 字节长,它将有 3 个扇区,而 fileSize/512将评估为 2.

如何修复:将 fileSize/512 替换为 (fileSize + 511) / 512