C文件拆分和合并 JNI中开启新线程

#include "jni.h"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <android/log.h>
#include <pthread.h>

#define TAG "Test_JNI"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__)
#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))

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

/**
 * 文件拆分
 */
JNIEXPORT void JNICALL nativeDiff(
        JNIEnv * env, jclass clazz,jstring path,jstring pattern_path,jint file_num){
    LOGI("开始分割");
    const char *path_str = (*env)->GetStringUTFChars(env,path,NULL);
    const char *path_pattern_str = (*env)->GetStringUTFChars(env,pattern_path,NULL);

    //申请字符串数组
    char **patches = (char **)malloc(sizeof(char*) * file_num);
    if(patches == NULL){
        return;
    }

    //给没一个文件命名
    int i = 0;
    long j = 0;
    for(i = 0;i<file_num;i++){
        patches[i] = (char*)malloc(sizeof(char)*100);
        if(patches[i] == NULL){
            return;
        }
        sprintf(patches[i],path_pattern_str,i);
    }

    int file_size = get_file_size(path_str);
    FILE *fpr = fopen(path_str,"rb");
    /*
  * 1.判断文件大小能够被 file_num整除
  * 2.能整除就平分
  * 3.不能整除就先分 file_num -1
  * */
    if(file_size%file_num == 0){
        long part = file_size/file_num;
        for(i = 0;i<file_num;i++){
            FILE *fpw = fopen(patches[i],"wb");
            for(j = 0;j<part;j++){
                fputc(fgetc(fpr),fpw);
            }
            fclose(fpw);
        }
    } else{
        long part = file_size/(file_num-1);
        for(i = 0;i<file_num-1;i++){
            FILE *fpw = fopen(patches[i],"wb");
            for(j = 0;j<part;j++){
                fputc(fgetc(fpr),fpw);
            }
            fclose(fpw);
        }
        FILE *fpw = fopen(patches[file_num-1],"wb");
        for(j = 0;j<file_size%(file_num-1);j++){
            fputc(fgetc(fpr),fpw);
        }
        fclose(fpw);
    }

    fclose(fpr);
    //释放文件
    for(int i=0;i<file_num;i++){
        free(patches[i]);
        patches[i] = NULL;
    }
    //释放字符串数组
    free(patches);
    (*env)->ReleaseStringUTFChars(env,path,path_str);
    (*env)->ReleaseStringUTFChars(env,pattern_path,path_pattern_str);
    LOGI("拆分结束");
}

/**
 * 文件合并
 */
JNIEXPORT void JNICALL nativePatch(
        JNIEnv * env, jclass clazz,jstring merge_path,jstring pattern_path,jint file_num){

    const char *path_merge = (*env)->GetStringUTFChars(env,merge_path,NULL);
    const char *path_pattern = (*env)->GetStringUTFChars(env,pattern_path,NULL);

    char **patchs = malloc(sizeof(char*) * file_num);
    int i;
    long j;
    long part_size;
    for(i = 0;i<file_num;i++){
        patchs[i] = malloc(sizeof(char)*100);
        sprintf(patchs[i],path_pattern,i);
    }

    FILE *fpw = fopen(path_merge,"wb");
    for(i = 0;i<file_num;i++){
        part_size = get_file_size(patchs[i]);
        FILE *fpr = fopen(patchs[i],"rb");
        for(j = 0;j<part_size;j++){
            fputc(fgetc(fpr),fpw);
        }
        fclose(fpr);
    }

    fclose(fpw);
    for(i = 0;i<file_num;i++){
        free(patchs[i]);
        patchs[i] = NULL;
    }
    free(patchs);
    patchs = NULL;
    (*env)->ReleaseStringUTFChars(env,merge_path,path_merge);
    (*env)->ReleaseStringUTFChars(env,pattern_path,path_pattern);
}

//开启新线程
JavaVM* g_jvm = NULL;
jobject g_obj = NULL;

/**
 * 开启新线程后调用的方法
 * @param arg
 * @return
 */
void *thread_fun(void *arg){
    JNIEnv *env;
    jclass  cls;
    jmethodID md,md1;

    if((*g_jvm)->AttachCurrentThread(g_jvm,&env,NULL) != JNI_OK){
        LOGI("%s AttachCurrentThread error failed ",__FUNCTION__);
        return NULL;
    }

    cls = (*env)->GetObjectClass(env,g_obj);
    if(cls == NULL){
        LOGI("findClass error....");
        goto error;
    }
    md = (*env)->GetStaticMethodID(env,cls,"formJni","(I)V");
    if(md == NULL){
        LOGI("GetStaticMethodID error....");
        goto error;
    }
    (*env)->CallStaticVoidMethod(env,cls,md,(int)arg);


    error:
    if((*g_jvm)->DetachCurrentThread(g_jvm) != JNI_OK){
        LOGI("%s DetachCurrentThread error failed ",__FUNCTION__);
    }
    pthread_exit(0);
}

//设置jniEnv 在Java的方法中调用
JNIEXPORT void JNICALL setJniEnv(
        JNIEnv * env, jobject jobj){
    (*env)->GetJavaVM(env,&g_jvm);
    g_obj = (*env)->NewGlobalRef(env,jobj);
}
//开启新线程 在Java的方法中调用
JNIEXPORT void JNICALL newJniThread(
        JNIEnv * env, jobject jobj){
    LOGI("开始开启线程");
    int i;
    pthread_t pt[5];
    for(i=0;i<5;i++){
        pthread_create(&pt[i],NULL,&thread_fun,(void*)i);
    }
}

//动态注册
static const JNINativeMethod getMethods[] = {
        {"diff","(Ljava/lang/String;Ljava/lang/String;I)V",(void *)nativeDiff},
        {"patch","(Ljava/lang/String;Ljava/lang/String;I)V",(void *)nativePatch}
};
static const JNINativeMethod getMainActivityMethods[] = {
        {"setJniEnv","()V",(void *)setJniEnv},
        {"newJniThread","()V",(void *)newJniThread}
};


static int registerNatives(JNIEnv *env){
    LOGI("注册FileUtils方法调用");
    jclass clazz;
    clazz = (*env)->FindClass(env,"cn/cct/lsn9/FileUtils");
    if(clazz == NULL){
        LOGI("注册方法调用失败");
        return JNI_FALSE;
    }

    if((*env)->RegisterNatives(env,clazz,getMethods,NELEM(getMethods)) < 0){
       LOGI("注册FileUtils失败");
        return JNI_FALSE;
    }
    return JNI_TRUE;
}
static int registerMainActivityNative(JNIEnv *env){
    LOGI("注册MainActivity方法调用");
    jclass clazz;
    clazz = (*env)->FindClass(env,"cn/cct/lsn9/MainActivity");
    if(clazz == NULL){
        LOGI("注册MainActivity失败");
        return JNI_FALSE;
    }
    if((*env)->RegisterNatives(env,clazz,getMainActivityMethods,NELEM(getMainActivityMethods)) < 0){
        LOGI("注册MainActivity失败");
        return JNI_FALSE;
    }
    return JNI_TRUE;
}


JNIEXPORT jint JNI_OnLoad(JavaVM * vm,void *reserved){
    LOGI("JNI_OnLoad函数开始调用");

    JNIEnv *env = NULL;

    if((*vm)->GetEnv(vm,(void**) &env,JNI_VERSION_1_4) != JNI_OK){
        LOGI("获取env失败");
        return -1;
    }
    assert(env != NULL);
    registerNatives(env);
    registerMainActivityNative(env);
    return JNI_VERSION_1_4;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值