android&java高效文件拆分与合并——NDK实现

发现在好久没有写了,乘着这个周未写一下,最近一直带实习生做项目,没有太多时间写,好了废话不多说下面开始文件的拆分:

所谓的文件拆分就是把一个文件拆分成若干个小文件:

首先我们要知道文件的大小,然后根据文件的大小和拆分数量计算每个小文件的大小,获取文件大小的代码如下:

//获取文件大小

long get_file_size(char *path){

FILE *fp = fopen(path,"rb");

fseek(fp,0,SEEK_END);

return ftell(fp);

}

下面就是文件拆分的具体实现:


JNIEXPORT void JNICALL Java_com_example_ndk_1file_NativeUtils_mDiff(JNIEnv *env,

jclass jcls, jstring path_jstr, jstring path_pattern_str, jint file_num) {

//获取分割路径

const char* path = (*env)->GetStringUTFChars(env, path_jstr, NULL);

const char* path_pattern = (*env)->GetStringUTFChars(env, path_pattern_str,

NULL);

//得到文件路径列表

char** patches = malloc(sizeof(char*) * file_num);

int i = 0;

for (; i < file_num; i++) {

patches[i] = malloc(sizeof(char) * 100);

sprintf(patches[i], path_pattern, (i + 1));

LOGI("patch path:%s", patches[i]);

}

/**

* 整除

* 文件大小:100,分成5个,每个文件20

* 不整除

* 文件大小:110,分成9个,每个文件13

* 前(9-1)个文件为(110/(9-1))=13

* 最后一个文件(110%(9-1))=6;

*

*/

int file_size = get_file_size(path);

FILE *fpr = fopen(path, "rb");

if (file_size % file_num == 0) {

//边读边写

int part = file_size / file_num;

i = 0;

//逐一写入不同的分割子文件中

for (; i < file_num; i++) {

FILE *fwp = fopen(patches[i], "wb");

int j = 0;

for (; j < part; j++) {

fputc(fgetc(fpr), fwp);

}

fclose(fwp);

}

}else{

//不能整除

int part = file_size / (file_num - 1);

i = 0;

//逐一写入不同的分割子文件中

for(; i < file_num-1; i++) {

FILE *fpw = fopen(patches[i], "wb");

int j = 0;for (; j < part; j++) {fputc(fgetc(fpr), fpw);

}

fclose(fpw);

}

FILE *fpw = fopen(patches[file_num-1],"wb");

i=0;

for(;iReleaseStringUTFChars(env, path_jstr, path);

(*env)->ReleaseStringUTFChars(env, path_pattern_str, path_pattern);

}

Native方法中需要传入,拆分文件的路径,小文件的命名规则,拆分个数。

文件的拆分已经完成,下面我们就进行文件的合并

文件的合并就是把若干个小文件合成一个可用的文件

首先我们要知道合并的原理,在上面的拆分中们们按照命名规则进行文件的拆分,那么下面就按照排好序的小文件合并,Native需要传入拆分的文件数量,拆分命名规则,和合并后文件存放路径,具体代码如下:

//合并

JNIEXPORT void JNICALL Java_com_example_ndk_1file_NativeUtils_mPatch(

JNIEnv *env, jclass jcls, jstring path_pattern_str, jint file_num,jstring total_str) {

//合并之后的路径

const char *merge_path = (*env)->GetStringUTFChars(env,total_str,NULL);

const char* path_pattern = (*env)->GetStringUTFChars(env, path_pattern_str,

NULL);

//得到文件路径列表

char** patches = malloc(sizeof(char*) * file_num);

int i = 0;

for (; i < file_num; i++) {

patches[i] = malloc(sizeof(char) * 100);

sprintf(patches[i], path_pattern, (i + 1));

LOGI("patch path:%s", patches[i]);

}

//把总文件写到一起

FILE *fwp = fopen(merge_path,"wb");

i=0;

for(;i

//每一个文件的大小

int filesize = get_file_size(patches[i]);

FILE *fpr = fopen(patches[i],"rb");

int j=0;

for(;j

fputc(fgetc(fpr),fwp);

}

fclose(fpr);

}

fclose(fwp);

}

总结:文件拆分其实有点像我们做下载的时候的断点续传,把文件拆分出来然后又合并回去得到完整的文件,在Android中主要用在增量更新。

你可能感兴趣的:(android&java高效文件拆分与合并——NDK实现)