NDK開發(fā)流程_文件的拆分與合并

前言

在上傳一些大的文件時候,用到文件的差分,和合并。這里是針對文件的二進制差分和合并,不區(qū)分格式

文件拆分

JNIEXPORT void JNICALL native_diff
(JNIEnv *env, jclass clazz, jstring path, jstring pattern_Path, jint file_num)
{
LOGI("JNI native diff begin");

const char path_Str = (env) -> GetStringUTFChars(env, path, NULL);
const char pattern_Path_str = (env) ->GetStringUTFChars(env, pattern_Path, NULL);
//申請二維字符數(shù)據(jù), 存放子文件名
char **patches = (char **)malloc(sizeof(char *) * file_num);

int i =0;
for (; i < file_num; i++) {
? //每個文件名申請地址
? LOGI("char = %d char * = %d", sizeof(char), sizeof(char ));
? patches[i] = (char
) malloc(sizeof(char) * 100);
? // 需要分割的文件 Vibrato.mp4
? // 每個子文件名稱 Vibrato_n.mp4
? sprintf(patches[i], pattern_Path_str, i);// 格式化文件名
? LOGI("patch path : %s",patches[i]);
}

int fileSize = get_file_size(path_Str);
FILE fpr = fopen(path_Str, "rb");
/

* 1.判斷文件大小能夠被 file_num整除
* 2.能整除就平分
* 3.不能整除就先分 file_num -1
* */
if (fileSize % file_num == 0) {
? int part = fileSize / file_num;
for (int i =0; i< file_num; i++) {
?? FILE *fpw = fopen(patches[i], "wb");//文件已經(jīng)存在 就刪除,只運行寫
?? for (int j =0; j < part; j++) {
?? fputc(fgetc(fpr), fpw);
}
?? fclose(fpw);
}
} else {
? int part = fileSize / (file_num - 1);
? for (int i =0 ; i< file_num - 1; i++) {
?? FILE fpw = fopen(patches[i], "wb");//文件已經(jīng)存在 就刪除,只運行寫
?? for (int j =0; j < part; j++) {
?? fputc(fgetc(fpr), fpw);
}
?? fclose(fpw);
}

? FILE fpw = fopen(patches[file_num - 1], "wb");
? for (int i = 0; i < fileSize % (file_num - 1); i++) {
?? fputc(fgetc(fpr),fpw);
}
? fclose(fpw);
}
? fclose(fpr);
for (int i =0; i< file_num; i++) {
free(patches[i]);
}
?? free(patches);
?? (
env)->ReleaseStringUTFChars(env, path, path_Str);
?? (
env)->ReleaseStringUTFChars(env, pattern_Path, pattern_Path_str);
}
分析圖:

image.png

文件合并

JNIEXPORT void JNICALL native_patch
(JNIEnv *env, jclass clazz, jstring merge_path, jstring pattern_Path, jint file_num)
{
LOGI("JNI native patch begin");
const char path_Str = (env) -> GetStringUTFChars(env, merge_path, NULL);
const char pattern_Path_str = (env) ->GetStringUTFChars(env, pattern_Path, NULL);
? //申請二維字符數(shù)據(jù), 存放子文件名
? char **patches = (char **)malloc(sizeof(char *) * file_num);
? int i =0;
? for (; i < file_num; i++) {
?? //每個文件名申請地址
??// LOGI("char = %d char * = %d", sizeof(char), sizeof(char ));
?? patches[i] = (char
) malloc(sizeof(char) * 100);
?? // 需要分割的文件 Vibrato.mp4
?? // 每個子文件名稱 Vibrato_n.mp4
??sprintf(patches[i], pattern_Path_str, i);// 格式化文件名

}
FILE fpw = fopen(path_Str, "wb");
? for (int i =0; i < file_num; i++) {
?? int filesize = get_file_size(patches[i]);
?? FILE fpr = fopen(patches[i], "rb");
? for (int j =0; j < filesize; j++) {
?? fputc(fgetc(fpr), fpw);
}
?? fclose(fpr);
}
?? fclose(fpw);
? for (int i =0; i< file_num; i++) {
?? free(patches[i]); //每一個malloc 對應(yīng)一個free
}
? free(patches);
?? (
env)->ReleaseStringUTFChars(env, merge_path, path_Str);
?? (
env)->ReleaseStringUTFChars(env, pattern_Path, pattern_Path_str);
}

//獲取文件大小
long get_file_size(const char* path) {
FILE *fp = fopen(path, "rb"); //打開一個文件, 文件必須存在,只運行讀
fseek(fp, 0, SEEK_END);
long ret = ftell(fp);
fclose(fp);
return ret;
}

.贊助本文及本系列,由老司機學(xué)院動腦學(xué)院特約贊助。
注意:Android jni目錄

最后編輯于
?著作權(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)容