我试图在C ++中创建一个文件分割器/连接器,但我的分割功能有问题。我使用MP4文件进行快速测试,结果是:其他所有部分都没问题,但最后一部分总是不起作用。我不明白这一点。有人可以向我解释一下吗?这是我的分割功能:
void split_F(const char* file_name, int number_of_part)
{
FILE *fp_read = fopen(file_name, "rb");
//calculate file size
int file_size;
fseek(fp_read, 0L, SEEK_END);
file_size = ftell(fp_read);
rewind(fp_read); //reset file pointer
//calculate number of parts
//int number_of_part = (int)ceil((double)file_size / size_of_part);
long size_of_part;
size_of_part = (int)floor((double)file_size / number_of_part);
cout << "Total files after split: " << number_of_part << endl
<< "...Processing..." << endl;
//main process
char name[255] = "";
for (int count = 1; count <= number_of_part; count++)
{
sprintf(name, "%s.part_%03d", file_name, count);
FILE *fp_write = fopen(name, "wb");
//create buffer
char *buffer = new char[size_of_part];
memset(buffer, NULL, size_of_part); //reset buffer
fread(buffer, size_of_part, 1, fp_read);
fwrite(buffer, size_of_part, 1, fp_write);
fseek(fp_read, count*size_of_part, SEEK_SET);
cout << "> File: " << name << " done babe!" << endl;
delete[] buffer;
fclose(fp_write);
}
fclose(fp_read);
}
答案 0 :(得分:1)
最后一部分可能比size_of_part更小或更大,因为原始文件大小不是它的倍数。
您需要自动调整最后一部分的大小。
例如,如果文件大小为1000字节,则为7个部分。 您的计算文件大小为142. 7 * 142 = 994,您缺少最后6个字节。这是你的问题吗?
不需要fseek,你为什么要使用它?您只需要按顺序读取输入文件
void split_F(const char* file_name, int number_of_part)
{
FILE *fp_read = fopen(file_name, "rb");
//calculate file size
int file_size;
fseek(fp_read, 0L, SEEK_END);
file_size = ftell(fp_read);
rewind(fp_read); //reset file pointer
//calculate number of parts
long size_of_part;
size_of_part = (int)ceil((double)file_size / number_of_part);
cout << "Total files after split: " << number_of_part << endl
<< "...Processing..." << endl;
//main process
char name[255] = "";
int bytesRemaining = file_size;
//create buffer, we reuse it for each part
char *buffer = new char[size_of_part];
//No need to reset buffer
//memset(buffer, NULL, partSize);
for (int count = 1; count <= number_of_part; count++)
{
sprintf(name, "%s.part_%03d", file_name, count);
FILE *fp_write = fopen(name, "wb");
int partSize;
if(bytesRemaining > size_of_part)
{
partSize = size_of_part;
}
else
{
partSize = bytesRemaining;
}
fread(buffer, partSize, 1, fp_read);
fwrite(buffer, partSize, 1, fp_write);
cout << "> File: " << name << " done babe!" << endl;
fclose(fp_write);
}
fclose(fp_read);
delete[] buffer;
}
答案 1 :(得分:0)
您正在计算size_of_part
作为文件大小和请求的部件数的舍入商。然后,您继续以该确切大小的块读取文件。除非文件大小是number_of_parts
的倍数,否则这将失败。您需要修复代码以允许最后一部分小于size_of_part
。
答案 2 :(得分:0)
您的文件可能不会分成相等长度的N个部分(假设文件长度为7个字节,您将其分为3个部分......?)
long remaining_size = file_size;
long size_of_part;
size_of_part = (file_size + number_of_part - 1) / number_of_part;
这使得零件长度向上舍入,因此最后一个零件可能比前面的所有零件短。
//create buffer
char *buffer = new char[size_of_part];
//main process
char name[255] = "";
for (int count = 1; count <= number_of_part; count++)
{
sprintf(name, "%s.part_%03d", file_name, count);
FILE *fp_write = fopen(name, "wb");
long this_part_size =
remaining_size < size_of_part ? remaining_size : size_of_part;
fread(buffer, this_part_size, 1, fp_read);
fwrite(buffer, this_part_size, 1, fp_write);
cout << "> File: " << name << " done babe!" << endl;
fclose(fp_write);
remaining_size -= this_part_size;
}
delete[] buffer;