安卓NDK开发案列三:文件的拆分与合并

来源:互联网 发布:php 判断是否含有中文 编辑:程序博客网 时间:2024/06/05 03:29

前言:关于文件的操作你可以使用java的io流可以对文件进行各种操作,这里我们就用到C来操作文件的复制、创建,通过JNI来实现文件的拆分与合并!如果你对C语言的IO使用不是很熟悉的话,请移步《C语言快速讲解(六)联合体、枚举、IO》!

---------分割线--------

展示效果:

---------分割线--------

java代码:MainActivity.java:

package com.fly.demo2;import android.os.Environment;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import java.io.File;public class MainActivity extends AppCompatActivity {    private FileUtils fileUtils;    private File splitfile;    private File outfile;    private File outmergefile;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        fileUtils = new FileUtils();        //要分割的文件地址        splitfile = new File(Environment.getExternalStorageDirectory(), "img.jpg");        outfile = new File(Environment.getExternalStorageDirectory(), "img%d.jpg");        outmergefile = new File(Environment.getExternalStorageDirectory(), "imgcorpy.jpg");    }    public void click1(View view) {        new Thread(new Runnable() {            @Override            public void run() {                fileUtils.split(splitfile.getAbsolutePath(), 2, outfile.getAbsolutePath());            }        }).start();    }    public void click2(View view) {        new Thread(new Runnable() {            @Override            public void run() {                fileUtils.merge(outfile.getAbsolutePath(), 2, outmergefile.getAbsolutePath());            }        }).start();    }}
FileUtils.java:
package com.fly.demo2;/** * Created by Fly on 2017/7/5. */public class FileUtils {    // 加载动态库    static {        System.loadLibrary("native-lib");    }    /**     * 分割文件     * @param splitFilePath 要分割的路径     * @param outPath 输出分割路径 其中每个文件末尾用%d代替   如 D:XXX%d.jpg     * @param number 分割数量     */    public  native void split(String splitFilePath,int number,String outPath);    /**     * 合并被分割的文件     * @param splitFilePath 被分割的文件路径 且有占位符 %d 如 D:XXX%d.jpg     * @param number 被分割的文件数目     * @param outPath 输出路径     */    public native void merge(String splitFilePath,int number,String outPath);}
C代码:
//// Created by Fly on 2017/7/5.//#include <jni.h>#include <stdlib.h>#include <stdio.h>#include<android/log.h>#define LOGE(FORMAT, ...) __android_log_print(ANDROID_LOG_ERROR,"FLY", FORMAT, __VA_ARGS__)long file_Size(char *path) {    FILE *filep = fopen(path, "rb");    fseek(filep, 0, SEEK_END);    return ftell(filep);}/* * Class:     com_fly_demo2_FileUtils * Method:    split_file * Signature: (Ljava/lang/String;ILjava/lang/String;)V */JNIEXPORT void JNICALL Java_com_fly_demo2_FileUtils_split        (JNIEnv *env, jobject job, jstring splitFilePath, jint number, jstring outPath) {//分隔文件的路径    char *splitFilePathChar = (*env)->GetStringUTFChars(env, splitFilePath, NULL);    //占位符路径 如 d:xxx%d.jpg    char *outPathChar = (*env)->GetStringUTFChars(env, outPath, NULL);    //输出分割文件的数组指针    FILE **fileArrayP = calloc(number, sizeof(FILE *));    //分割数据FILE    FILE *splitFile = fopen(splitFilePathChar, "rb");    //文件大小    long fileSize = file_Size(splitFilePathChar);    //每个每个文件大小    long file_black_size[number];    LOGE("文件总大小:%ld", fileSize);    //初始化循环变量    int var = 0;    //每个分割文件大小    long blackSize = fileSize / number;    //循环遍历赋值每个文件    for (; var < number; ++var) {        //每一个输出文件的地址        char *outEachPath = calloc(200, sizeof(char));        //格式化文件输出路径        sprintf(outEachPath, outPathChar, var);        //每个文件指向        fileArrayP[var] = fopen(outEachPath, "wb");        //释放        free(outEachPath);        //最后一个        if (var == number - 1) {            //最后一个文件的大小 防止不能被整除            file_black_size[number - 1] = blackSize + fileSize % number;        } else {            //每个文件的文件大小 注意如果文件大小不能被number整数那么最后一个文件大小需要重新计算赋值            file_black_size[var] = blackSize;        }    }    //从文件中读取的byte    int ch;    long current = 0;//当前进度    //所有分割数    for (var = 0; var < number; ++var) {        //最后一块        if (var == number - 1) {            while ((ch = fgetc(splitFile)) != EOF) {                fputc(ch, fileArrayP[var]);            }        } else {            while (current < blackSize) {                ch = fgetc(splitFile);                current++;                fputc(ch, fileArrayP[var]);            }        }        fclose(fileArrayP[var]);        //充值下标        current = 0;    }    free(fileArrayP);    //释放指向    (*env)->ReleaseStringUTFChars(env, splitFilePath, splitFilePathChar);    (*env)->ReleaseStringUTFChars(env, outPath, outPathChar);}/* * Class:     com_fly_demo2_FileUtils * Method:    merge_file * Signature: (Ljava/lang/String;ILjava/lang/String;)V */JNIEXPORT void JNICALL Java_com_fly_demo2_FileUtils_merge        (JNIEnv *env, jobject job, jstring splitFilePath, jint count, jstring outFilePath) {//占位符路径 如 d:xxx%d.jpg    char *splitFilePathChar = (*env)->GetStringUTFChars(env, splitFilePath, NULL);    //合并文件路徑    char *outFilePathChar = (*env)->GetStringUTFChars(env, outFilePath, NULL);    int var;    //打开输出文件    FILE *outFilep = fopen(outFilePathChar, "wb");    for (var = 0; var < count; ++var) {        //分割文件路径名        char *splitFilePathEeatChar = calloc(200, sizeof(char));        //格式化路径        sprintf(splitFilePathEeatChar, splitFilePathChar, var);        //打开被分割的文件        FILE *filep = fopen(splitFilePathEeatChar, "rb");        int ch;        while ((ch = fgetc(filep)) != EOF) {            fputc(ch, outFilep);        }        free(filep);        fclose(filep);    }    //关闭输出文件指向    fclose(outFilep);    //释放指向    (*env)->ReleaseStringUTFChars(env, splitFilePath, splitFilePathChar);    //释放指向    (*env)->ReleaseStringUTFChars(env, outFilePath, outFilePathChar);}
--------完-------

原创粉丝点击