NDK开发流程_文件的拆分与合并

前言

在上传一些大的文件时候,用到文件的差分,和合并。这里是针对文件的二进制差分和合并,不区分格式

文件拆分

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);
//申请二维字符数据, 存放子文件名
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");//文件已经存在 就删除,只运行写
   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");//文件已经存在 就删除,只运行写
   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);
}
分析图:

NDK开发流程_文件的拆分与合并_第1张图片
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);
  //申请二维字符数据, 存放子文件名
  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 对应一个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;
}

.赞助本文及本系列,由老司机学院动脑学院特约赞助。
注意:Android jni目录

你可能感兴趣的:(NDK开发流程_文件的拆分与合并)