通过使用JNI完成对本地文件的拆分与合并
1、MainActivity.java
public class MainActivity extends AppCompatActivity {
private String SD_CARD_PATH ;
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SD_CARD_PATH = getCacheDir().getPath();
}
//拆分
public void mDiff(View view){
Log.d("MainActivity", SD_CARD_PATH);
String path = SD_CARD_PATH + File.separatorChar+ "sintel.mp4";
String path_pattern = SD_CARD_PATH +File.separatorChar+ "sintel_%d.mp4";
NDKFileUtils.diff(path,path_pattern,3);
Log.d("MainActivity", "拆分完毕");
}
//合并
public void mPatch(View view){
String path_pattern = SD_CARD_PATH +File.separatorChar+ "sintel_%d.mp4";
String merge_path = SD_CARD_PATH +File.separatorChar+ "sintel_merge.mp4";
NDKFileUtils.patch(path_pattern,3,merge_path);
Toast.makeText(this, "合并", Toast.LENGTH_SHORT).show();
}
}
2、NDKFileUtils.java
public class NDKFileUtils {
/**
* 拆分
* @param path
* @param path_pattern
* @param count
*/
public native static void diff(String path,String path_pattern,int count);
/**
* 合并
* @param path_pattern
* @param count
* @param merge_path
*/
public native static void patch(String path_pattern,int count,String merge_path);
}
3、native-lib.cpp
#include <jni.h>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <android/log.h>
#define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO,"jason",FORMAT,__VA_ARGS__)
#define LOGE(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR,"jason",FORMAT,__VA_ARGS__)
//获取文件大小
long get_file_size(char *path){
FILE *fp = fopen(path,"rb");
fseek(fp,0,SEEK_END);
return ftell(fp);
}
//拆分
extern "C"
JNIEXPORT void JNICALL
Java_com_example_ndk0819_NDKFileUtils_diff(JNIEnv *env, jclass type, jstring path_,
jstring path_pattern_, jint count) {
/*需要分割的文件路径*/
const char *path = env->GetStringUTFChars(path_, 0);
const char *path_pattern = env->GetStringUTFChars(path_pattern_, 0);
// TODO
//1.得到分割自后子文件的路径列表
char **patches= static_cast<char **>(malloc(sizeof(char*) * count));
int i=0;
for (; i < count; ++i) {
patches[i]= static_cast<char *>(malloc(sizeof(char) * 100));
//元素赋值
//需要分割的文件:C://jason/liuyan.png
//子文件:C://jason/liuyan_%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(const_cast<char *>(path));
FILE *fpr=fopen(path,"rb");
//整除
if (filesize%count==0){
//单个文件大小
int part = filesize / count;
i=0;
for (; i < count; ++i) {
FILE *fpw = fopen(patches[i], "wb");
int j = 0;
for(; j < part; j++){
//边读边写
fputc(fgetc(fpr),fpw);
}
fclose(fpw);
}
} else{
//不整除
int part = filesize / (count - 1);
i = 0;
//逐一写入不同的分割子文件中
for (; i < count - 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[count - 1], "wb");
i = 0;
for(; i < filesize % (count - 1); i++){
fputc(fgetc(fpr),fpw);
}
fclose(fpw);
}
//关闭被分割的文件
fclose(fpr);
//释放
i=0;
for (; i < count; ++i) {
free(patches[i]);
}
free(patches);
env->ReleaseStringUTFChars(path_, path);
env->ReleaseStringUTFChars(path_pattern_, path_pattern);
}
//合并
extern "C"
JNIEXPORT void JNICALL
Java_com_example_ndk0819_NDKFileUtils_patch(JNIEnv *env, jclass type, jstring path_pattern_,
jint count, jstring merge_path_) {
const char *path_pattern = env->GetStringUTFChars(path_pattern_, 0);
const char *merge_path = env->GetStringUTFChars(merge_path_, 0);
//得到分割之后的子文件的路径列表
char **patches = static_cast<char **>(malloc(sizeof(char*) * count));
int i = 0;
for (; i < count; i++) {
patches[i] = static_cast<char *>(malloc(sizeof(char) * 100));
//元素赋值
//需要分割的文件:C://jason/liuyan.png
//子文件:C://jason/liuyan_%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 < count; i++){
//每个子文件的大小
int filesize = get_file_size(patches[i]);
FILE *fpr = fopen(patches[i], "rb");
int j = 0;
for (; j < filesize; j++) {
fputc(fgetc(fpr),fpw);
}
fclose(fpr);
}
fclose(fpw);
//释放
i = 0;
for(; i < count; i++){
free(patches[i]);
}
free(patches);
env->ReleaseStringUTFChars(path_pattern_, path_pattern);
env->ReleaseStringUTFChars(merge_path_, merge_path);
}