2015-04-17 64 views
0

我想在C++中创建一个文件分割器/连接器,并且我的分割函数有问题。我用一个MP4文件进行了快速测试,结果是:其他部分都可以,但最后一部分总是不起作用。我不明白这一点。任何人都可以请给我解释一下吗?这里是我的分裂功能:C++中的文件分割器

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); 
} 
+2

这不是C,那是C++。 – mch

+0

哎呀对不起,我的大学教两个,所以我很困惑 – YaphatS

+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; 
} 
+0

你的意思是说最后一部分必须单独书写吗?如果是这样,那么最后一部分的大小是多少?我想这是 long remaining_size = file_size - (number_of_part - 1)* size_of_part; 如果我错了,请纠正我的错误 – YaphatS

+0

不,请参阅我的更新代码。写入的字节数将是可变的,并且等于剩余字节总数和size_of_part的最小值 – galinette

+0

请注意,我使用“ceil”而不是“floor”来避免丢失最后部分中的一些字节 – galinette

0

您计算size_of_part文件大小的圆形商和零部件的请求数量。然后,您继续以大小确切的大小读取文件。这将失败,除非文件大小是number_of_parts的倍数。你需要修正你的代码,让最后一部分小于size_of_part

+0

这是不正确的;因为他使用'floor',所以最后一部分会比'size_of_part'大 – galinette

+0

@galinette好点,尽管OP在此期间编辑了他的答案。然而,正确写入的分割器决不允许块大于规定的块大小(例如因为它不适合固定大小的媒体),所以应答中的文本应该适用。 – user4815162342

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;