因此,虽然我理解了恢复的大部分代码......我在理解它的某些部分时遇到了麻烦。我已经写了一个我认为在代码中发生的事情的总结,如果有人能纠正我,如果我的解释是错误的,我将不胜感激。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char *argv[])
{
// Check how many input commands
if (argc != 2)
{
printf("Invalid Usage. Try ./recover IMAGE\n");
return 1;
}
// Open file and make sure input file is valid
FILE* input_file = fopen(argv[1], "r");
if (input_file == NULL)
{
printf("Could not open file.\n");
return 2;
}
// Buffer to read through each block of memory
uint8_t buffer[512] = {0};
// Count number of images
int count_image = 0;
// Creating output file
FILE* output_file = NULL;
// Allocating space for output file name
char* filename = malloc(sizeof(char));
// Reading through the input file
while (fread(buffer, sizeof(uint8_t), 512, input_file))
{
// Checking for JPEG header
if ((buffer[0] == 0xff) && (buffer[1] == 0xd8) && (buffer[2] == 0xff) && ((buffer[3] & 0xf0) == 0xe0))
{
// Write JPEG filename
sprintf(filename, "%03i.jpg", count_image);
// Open output file
output_file = fopen(filename, "w");
// Increment image
count_image++;
}
// If file hasn't been been used yet
if (output_file != NULL)
{
fwrite(buffer, sizeof(uint8_t), 512, output_file);
}
}
free(filename);
fclose(output_file);
fclose(input_file);
return 0;
}
字符串
因此,在这个问题中,我们应该恢复JPEG的。存储卡有一堆512字节大小的块。JPEG可以使用多个512大小的块,任何多余的空间都用0填充。
我们首先做一些标准的事情,确保输入是有效的,并且输入文件打开时没有任何错误。然后我们初始化一个缓冲区来存储512字节大小的块,这样我们就可以一次遍历存储卡的一个块。然后我们初始化count-image来计数图像,以及一个名为output-file的空指针。最后,我们初始化另一个指针filename,为存储输出文件的文件名腾出空间。
现在我们打开while循环。这里我使用了uint8_t,这意味着我们将迭代512字节块中的每个字节,直到文件结束。如果我们到达文件的末尾,并且一个字节不能再被读取,fread将返回0,while循环将退出。所以现在我们有了buffer,它是一个大小为512的数组,由512个8位元素组成。
现在,我们检查缓冲区的第一个、第二个、第三个和第四个元素是否与JPEG标头的序列匹配。如果是,我们使用sprintf将该文件的名称存储在filename指向的内存中。
由于我们已经开始阅读JPEG,我们现在将空指针output-file分配给一个新文件,我们使用filename中存储的字符串打开该文件。我的问题是...fopen是否创建新文件?
然后我们增加计数器。这样,我们打印的图像从0到49,而不是0到50,如果我们要在sprintf之前计数图像。
然后,由于我们已经分配了指针,它不再是null,我们进入下一个if语句,并将缓冲区中存储的任何内容写入输出文件。
现在我们检查下一个512字节块。如果它没有以JPEG头开始,那么我们继续将其写入同一个输出文件,因为这意味着它是第一个图像的延续。
当我们找到第二个JPEG标头时,sprintf将“1”存储在filename所指向的地址处。然后我们以写模式打开一个新文件,新文件名为“1”。然后在递增计数器之后,我们现在开始写入新文件,因为指针现在指向新文件。
然后我们重复相同的过程,直到文件结束,创建50个文件,每个文件由一个JPEG图像组成,命名为0.jpg到49.jpg。(问题中提到,总共有50张图片)
运行这段代码似乎产生了一个内存泄漏….是因为我没有在打开下一个输出文件之前关闭每个输出文件吗?
1条答案
按热度按时间z18hc3ub1#
1.是的,如果
fopen(filename,"w")
不存在,则fopen(filename,"w")
创建filename
,如果存在,则将其截断为0字节(参见man page)。1.你说得对。在打开一个新文件之前不关闭
output_file
是一个bug,会导致内存泄漏。1.这一行是错误的:
char* filename = malloc(sizeof(char));
。它只分配一个字节,但你至少需要8个字节,包括'\0'
(假设你最多找到999张图像)