读取时将额外的字符添加到文件末尾
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
。
我正在将一个文件从 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
。