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);
}