jni 文件的拆分与合并

java代码
//文件拆分
   public void mDiff(View btn){
//        String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath();
        String path = "/sdcard/Download" + File.separatorChar +"wushen.mp4";
        String path_pattern = "/sdcard/Download" + File.separatorChar +"wushen_%d.mp4";
        diff(path,path_pattern,3);
        Log.i(TAG,"拆分完成");
    }
    public native void diff(String path,String path_pattern,int file_count);
    //文件合并
    public void mPatch(View btn){
        String path = "/sdcard/Download" + File.separatorChar +"wushen_merge.mp4";
        String path_pattern = "/sdcard/Download" + File.separatorChar +"wushen_%d.mp4";
        patch(path_pattern,3,path);
        Log.i(TAG,"拆分完成");
    }
    public native void patch(String path_pattern,int count,String total_path);

c代码
char **a; 需要至少两次分配内存,1次为二级指针,分配字符串,所需指针,占用的内存,即有几个字符串,分配几个字符指针的内存。
还需要一次或者多次,为每个字符串分配内存。

#define LOGI(FORMAT, ...)   __android_log_print(ANDROID_LOG_INFO,"lgj ",FORMAT,__VA_ARGS__)
long get_file_size(char *path) {
    FILE *file = fopen(path, "rb");
    //让文件指针直接从0 移动到文件末尾,就可以获取文件的大小
    fseek(file, 0, SEEK_END);
    return ftell(file);
}

JNIEXPORT void JNICALL Java_com_example_jnitest_MainActivity_diff
        (JNIEnv *env, jobject jobj, jstring path_jstr, jstring path_pattern_jstr, jint file_count) {
    //分割的文件路径
    const char *path = (*env)->GetStringUTFChars(env, path_jstr, NULL);
    //拆分之后的文件路径
    const char *path_pattern = (*env)->GetStringUTFChars(env, path_pattern_jstr, NULL);
    char **patches = malloc(sizeof(char *) * file_count);
    int i = 0;
    for (; i < file_count; i++) {
        patches[i] = malloc(sizeof(char) * 100);
        //文件的格式 /sdcard/Download/wushen.mp4
        //分割之后文件的格式为 /sdcard/Download/wushen_01.mp4
        //分割之后文件的格式为 /sdcard/Download/wushen_02.mp4
        //分割之后文件的格式为 /sdcard/Download/wushen_03.mp4
        sprintf(patches[i], path_pattern, (i + 1));
        LOGI("patch path:%s", patches[i]);
    }
    //获取文件的大小
    long file_size = get_file_size(path);
    //打开文件,返回文件指针类型
    FILE *fpr = fopen(path, "rb");
    //能整除的情况下
    if (file_size % file_count == 0) {
        //获取每部分的文件大小
        long part = file_size / file_count;
        i = 0;
        for (; i < file_count; i++) {
            //获取要写入的文件指针
            FILE *fpw = fopen(patches[i], "wb");
            int j = 0;
            for (; j < part; j++) {
                //边读边写
                fputc(fgetc(fpr), fpw);
            }
            fclose(fpw);
        }

    } else {
        long file_size = get_file_size(path);
        long part = file_size / file_count - 1;
        i = 0;
        for (; i < file_count - 1; i++) {
            FILE *fpw = fopen(patches[i], "wb");
            int j = 0;
            for (; j < part; j++) {
                fputc(fgetc(fpr), fpw);
            }
            fclose(fpw);
        }
        // 104 分成9 份,避免最后一个文件创建为空
        if (file_size % (file_count - 1) != 0) {
            i = 0;
            FILE *fpw = fopen(patches[file_count - 1], "wb");
            for (; i < file_size % (file_count - 1); i++) {
                fputc(fgetc(fpr), fpw);
            }
            fclose(fpw);
        }
    }
    fclose(fpr);
    i = 0;
    //释放内存
    for (; i < file_count; i++) {
        free(patches[i]);
    }
    free(patches);

    //C 中字符串用完之后释放掉
    (*env)->ReleaseStringUTFChars(env, path_jstr, path);
    (*env)->ReleaseStringUTFChars(env, path_pattern_jstr, path_pattern);
}

JNIEXPORT void JNICALL Java_com_example_jnitest_MainActivity_patch
        (JNIEnv *env, jobject jobj, jstring path_pattern_jstr, jint file_count,
         jstring path_jstr) {
    const char *total_path = (*env)->GetStringUTFChars(env, path_jstr, NULL);
    const char *pattern_path = (*env)->GetStringUTFChars(env, path_pattern_jstr, NULL);
    //创建字符数组
    char **patches = malloc(sizeof(char *) * file_count);
    int i = 0;
    for (; i < file_count; ++i) {
        patches[i] = malloc(sizeof(char)*100);
        sprintf(patches[i],pattern_path,i + 1);
        LOGI("patch path:%s", patches[i]);
    }
    //把所有的分割文件读取,写入一个总的文件
    FILE * fpw = fopen(total_path,"wb");
    i = 0;
    for (; i < file_count; i++) {
        long part_size = get_file_size(patches[i]);
        //打开文件,直接返回对应文件的指针
        FILE * fpr = fopen(patches[i],"rb");
        int j = 0;
        for (; j < part_size; j++) {
            fputc(fgetc(fpr),fpw);
        }
        fclose(fpr);
    }
    fclose(fpw);

    //释放内存
    for (; i < file_count; i++) {
        free(patches[i]);
    }
    free(patches);

    //C 中字符串用完之后释放掉
    (*env)->ReleaseStringUTFChars(env, path_jstr, total_path);
    (*env)->ReleaseStringUTFChars(env, path_pattern_jstr, pattern_path);
}

猜你喜欢

转载自blog.csdn.net/weixin_39413778/article/details/82744973
JNI