android&java高效文件拆分與合并——NDK實現(xiàn)

發(fā)現(xiàn)在好久沒有寫簡書了,乘著這個周未寫一下,最近一直帶實習(xí)生做項目,沒有太多時間寫,好了廢話不多說下面開始文件的拆分:

所謂的文件拆分就是把一個文件拆分成若干個小文件:

首先我們要知道文件的大小,然后根據(jù)文件的大小和拆分?jǐn)?shù)量計算每個小文件的大小,獲取文件大小的代碼如下:

//獲取文件大小

long get_file_size(char *path){

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

fseek(fp,0,SEEK_END);

return ftell(fp);

}

下面就是文件拆分的具體實現(xiàn):


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

* 不整除

* 文件大?。?10,分成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方法中需要傳入,拆分文件的路徑,小文件的命名規(guī)則,拆分個數(shù)。

文件的拆分已經(jīng)完成,下面我們就進(jìn)行文件的合并

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

首先我們要知道合并的原理,在上面的拆分中們們按照命名規(guī)則進(jìn)行文件的拆分,那么下面就按照排好序的小文件合并,Native需要傳入拆分的文件數(shù)量,拆分命名規(guī)則,和合并后文件存放路徑,具體代碼如下:

//合并

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<file_num;i++){

//每一個文件的大小

int filesize = get_file_size(patches[i]);

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

int j=0;

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

fputc(fgetc(fpr),fwp);

}

fclose(fpr);

}

fclose(fwp);

}

總結(jié):文件拆分其實有點像我們做下載的時候的斷點續(xù)傳,把文件拆分出來然后又合并回去得到完整的文件,在Android中主要用在增量更新。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容