JNI之文件的拆分和合并

1,接口,

public class NDKFileUtils {
    // 拆分
    public native static void diff(String path,String path_pattern,int count);

    // 合并
    public native static void patch(String path_pattern,int count,String merge_path);
}

2,头文件

/*
 * Class:     com_XXX_XXX_XXX_patch_NDKFileUtils
 * Method:    piff
 * Signature: (Ljava/lang/String;I)V
 */
JNIEXPORT void JNICALL Java_com_XXX_XXX_XXX_patch_NDKFileUtils_diff
  (JNIEnv *, jclass, jstring, jstring ,jint);

/*
 * Class:     com_XXX_XXX_XXX_patch_NDKFileUtils
 * Method:    patch
 * Signature: (Ljava/lang/String;I)V
 */
JNIEXPORT void JNICALL Java_com_XXX_XXX_XXX_patch_NDKFileUtils_patch
  (JNIEnv *, jclass, jstring, jint, jstring );

3,C++方法。

// 获取文件大小
long get_file_size(const char * path){
    FILE * fp = fopen(path,"rb");
    fseek(fp,0,SEEK_END);
    return ftell(fp);
}

// 拆分
extern "C" JNIEXPORT void JNICALL
Java_com_XXX_XXX_XXX_patch_NDKFileUtils_diff
        (JNIEnv *env, jclass jcls, jstring path_jstr, jstring path_pattern_jstr, jint file_num) {
    // jstring->char *
    // 需要分割的文件路径
    const char *path = env->GetStringUTFChars(path_jstr, NULL);
    const char *path_pattern = env->GetStringUTFChars(path_pattern_jstr, NULL);
    // 得到分割之后的子文件的路径列表
    char **patches = (char **) malloc(sizeof(char *) * file_num);
    int i = 0;
    for (; i < file_num; i++) {
        patches[i] = (char *) malloc(sizeof(char) * 100);
        // 元素赋值
        // 需要分割的文件  c://jason/hh.png
        // 子文件 c://jason/hh_%d.png
        sprintf(patches[i], path_pattern, (i + 1));
        LOGI("patch path:%s", patches[i]);

    }


    // 不断读取path文件,循环去写入file_num个文件中
    // 整除,
    // 文件大小90,分成9份,每个文件10
    // 不整除
    // 文件大小110,分成9份,
    // 前(9-1)个文件为(110/(9-1)) = 13
    // 最后一个文件(110%(9-1)) = 6
    int filesize = get_file_size(path);
    FILE * fpr = fopen(path,"rb");
    if (filesize * file_num == 0){
        // 整除
        // 单个文件的大小
        int part = filesize /file_num;
        int i = 0;
        // 逐一写入不同的分割子文件中
        for (; i < file_num; i++) {
            FILE * fpw = fopen(patches[i],"wb");
            int j = 0;
            for (; j<part;j++){
                // 边读边写
                fputc(fgetc(fpr),fpw);
            }
            fclose(fpw);
        }
        fclose(fpr);
    } else{
        // 不能整除
        int part = filesize/(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 (;i<filesize%(file_num -1);i++){
            fputc(fgetc(fpr),fpw);
        }
        fclose(fpw);
    }
    // 关闭被分割的文件
    fclose(fpr);

    // 释放
    i = 0;
    for(; i< file_num; i++){
        free(patches[i]);
    }
    free(patches);

    // 只要用到GetStringUTFChars这个方法的,最后都需要ReleaseStringUTFChars来进行释放。
    env->ReleaseStringUTFChars(path_jstr, path);
    env->ReleaseStringUTFChars(path_pattern_jstr, path_pattern);

}

// 合并
extern "C" JNIEXPORT void JNICALL
Java_com_XXX_XXX_XXX_patch_NDKFileUtils_patch
        (JNIEnv *env, jclass jcls, jstring path_pattern_jstr,jint file_num, jstring merge_path_jstr) {
    // 合并之后的文件
    const char *merge_path = env->GetStringUTFChars(merge_path_jstr, NULL);
    // 分割子文件的pattern
    const char *path_pattern = env->GetStringUTFChars(path_pattern_jstr, NULL);

    // 得到分割之后的子文件的路径列表
    char **patches = (char **) malloc(sizeof(char *) * file_num);
    int i = 0;
    for (; i < file_num; i++) {
        patches[i] = (char *) malloc(sizeof(char) * 100);
        // 元素赋值
        // 需要分割的文件  c://jason/hh.png
        // 子文件 c://jason/hh_%d.png
        sprintf(patches[i], path_pattern, (i + 1));
        LOGI("patch path:%s", patches[i]);

    }

    FILE * fpw = fopen(merge_path,"wb");
    // 把所有的分割文件读取一遍,写入一个总的文件中
    i = 0;
    for (; i< file_num;i++){
        // 每个子文件的大小
        int fliesize = get_file_size(patches[i]);
        FILE * fpr = fopen(patches[i],"rb");
        int j = 0;
        for (;j<fliesize;j++){
            fputc(fgetc(fpr),fpw);
        }
        fclose(fpr);
    }
    fclose(fpw);

    // 释放
    i = 0;
    for(; i< file_num; i++){
        free(patches[i]);
    }
    free(patches);

    env->ReleaseStringUTFChars(path_pattern_jstr, path_pattern);
    env->ReleaseStringUTFChars(merge_path_jstr, merge_path);

}

 

4,调用

//拆分
public void mDiff(View view) {
    String path = SD_CARD_PATH + File.separatorChar + "timg-2.jpg";
    String path_pattern = SD_CARD_PATH + File.separatorChar + "timg-2_%d.jpg";
    NDKFileUtils.diff(path,path_pattern,3);
    Log.e("LOG","拆分完毕.....");
}

// 合并
public void mPatch(View view) {
    String path_pattern = SD_CARD_PATH + File.separatorChar + "timg-2_%d.jpg";
    String merge_path = SD_CARD_PATH + File.separatorChar + "timg-merge.jpg";
    NDKFileUtils.patch(path_pattern,3,merge_path);
    Log.e("LOG","合并完毕.....");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值