發(fā)現(xiàn)在好久沒有寫簡書了,乘著這個周未寫一下峡眶,最近一直帶實習生做項目辫樱,沒有太多時間寫,好了廢話不多說下面開始文件的拆分:
所謂的文件拆分就是把一個文件拆分成若干個小文件:
首先我們要知道文件的大小,然后根據(jù)文件的大小和拆分數(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
* 不整除
* 文件大杏诒小: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方法中需要傳入介蛉,拆分文件的路徑蚤氏,小文件的命名規(guī)則竿滨,拆分個數(shù)。
文件的拆分已經(jīng)完成于游,下面我們就進行文件的合并
文件的合并就是把若干個小文件合成一個可用的文件
首先我們要知道合并的原理,在上面的拆分中們們按照命名規(guī)則進行文件的拆分倾剿,那么下面就按照排好序的小文件合并蚌成,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中主要用在增量更新拌阴。