04.Eclipse下Ndk开发(以文件拆分合并为例模拟一下开发过程,参考文件加密的过程)-阿里云开发者社区

开发者社区> 黑夜路口> 正文

04.Eclipse下Ndk开发(以文件拆分合并为例模拟一下开发过程,参考文件加密的过程)

简介: (创建于2017/12/6) 1.工具类PatchUtils package com.ren.ndk_file_patch; public class PatchUtils { static{ System.
+关注继续查看

(创建于2017/12/6)

1.工具类PatchUtils

package com.ren.ndk_file_patch;

public class PatchUtils {
    
    static{
        System.loadLibrary("ndk_file_patch");
    }

    public native static void diff(String path,String path_pattern,int count);
    
    public native static void patch(String path_pattern,String merge_path,int count);
}

2.生成的头文件 com_ren_ndk_file_patch_PatchUtils.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_ren_ndk_file_patch_PatchUtils */

#ifndef _Included_com_ren_ndk_file_patch_PatchUtils
#define _Included_com_ren_ndk_file_patch_PatchUtils
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_ren_ndk_file_patch_PatchUtils
 * Method:    diff
 * Signature: (Ljava/lang/String;Ljava/lang/String;I)V
 */
JNIEXPORT void JNICALL Java_com_ren_ndk_1file_1patch_PatchUtils_diff
  (JNIEnv *, jclass, jstring, jstring, jint);

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

#ifdef __cplusplus
}
#endif
#endif

3.编写的c文件 ndk_file_patch.c

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

#define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO,"renzhenming",FORMAT,__VA_ARGS__);
#define LOGE(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR),"renzhenming",FORMAT,__VA_ARGS__);

long get_file_size(const char *path){
    FILE *fl = fopen(path,"rb");
    //把与fp有关的文件位置指针放到一个指定位置。
    //文件指针定位到文件末尾,偏移0个字节 
    fseek(fl,0,SEEK_END);
    //函数用来获取文件读写指针的当前位置,对于二进制文件,则返回从文件开头到结尾的字节数。
    return ftell(fl);
}

JNIEXPORT void JNICALL Java_com_ren_ndk_1file_1patch_PatchUtils_diff
  (JNIEnv *env, jclass jclz, jstring path_jstr, jstring path_pattern_jstr, jint file_num){

    //转换文件路径
    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_num);

    int i = 0;
    for(;i<file_num;i++){
        patches[i]=malloc(sizeof(char)*100);
        //元素赋值
        //需要分割的文件:C://jason/liuyan.png
        //子文件:C://jason/liuyan_%d.png(path_pattern的格式)
        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 file_size = get_file_size(path);
    //打开这个文件
    FILE *fpr = fopen(path,"rb");

    //整除
    if(file_size % file_num == 0){
        //单个文件大小
        int part = file_size/file_num;

        int i =0;
        //逐一写入设置好的子文件路径中
        for(;i<file_num;i++){
            //从子文件路径打开一个FILE
            FILE *fpw = fopen(patches[i],"wb");
            int j = 0;
            for(;j<part;j++){
                //边读边写
                //fgetc函数功能:从流中读取字符,即从fp所指定的文件中取得下一个字符。这里需要注意,在每取完一个字符时fp会自动向下移动一个字节。这样编成时,程序员就不用再对fp                 //控制了。这种功能在许多读写函数中都有体现。
                fputc(fgetc(fpr),fpw);
            }
            fclose(fpw);
        }
    }else{
        //无法整除
        int part = file_size/(file_num-1);
        int 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<file_size%(file_num-1);i++){
            fputc(fgetc(fpr),fpw);
        }
        fclose(fpw);
    }

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

    (*env)->ReleaseStringUTFChars(env,path_jstr,path);
    (*env)->ReleaseStringUTFChars(env,path_pattern_jstr,path_pattern);
}

/*
 * Class:     com_ren_ndk_file_patch_PatchUtils
 * Method:    patch
 * Signature: (Ljava/lang/String;Ljava/lang/String;I)V
 */
JNIEXPORT void JNICALL Java_com_ren_ndk_1file_1patch_PatchUtils_patch
  (JNIEnv *env, jclass jclz, jstring path_pattern_jstr, jstring merge_path_jstr, jint file_num){
    //字符串转换
    const char *merge_path = (*env)->GetStringUTFChars(env,merge_path_jstr,NULL);
    const char *path_pattern = (*env)->GetStringUTFChars(env,path_pattern_jstr,NULL);
    //得到分割后的子文件路径列表
    char **patches = malloc(sizeof(char*)*file_num);
    int i = 0;
    for(;i<file_num;i++){
        patches[i]=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]);
    }
    //打开要merge_path为一个FILE
    FILE *fpw = fopen(merge_path,"wb");
    //把所有分割的文件读取一遍,写入到这个总的文件中
    i = 0;
    for(;i<file_num;i++){
        //得到每个子文件的大小
        int file_size = get_file_size(patches[i]);
        //打开每个子文件路径为一个FILE
        FILE *fpr = fopen(patches[i],"rb");
        int j =0;
        for(;j<file_size;j++){
            fputc(fgetc(fpr),fpw);
        }
        fclose(fpr);
    }
    fclose(fpw);

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

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

4.Android.mk文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := ndk_file_patch
LOCAL_SRC_FILES := ndk_file_patch.c
LOCAL_LDLIBS := -llog   //使用了log,需要引入

include $(BUILD_SHARED_LIBRARY)

5.开始拆分合并

public class MainActivity extends Activity {
    private String SD_CARD_PATH;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SD_CARD_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();
    }
    
    public void diff(View view){
        String path = SD_CARD_PATH +File.separatorChar+ "2.mp4";
        String path_pattern = SD_CARD_PATH +File.separatorChar+ "2_%d.mp4";
        PatchUtils.diff(path, path_pattern, 2);
        System.out.println("拆分完成");
    }
    public void patch(View view){
        String merge_path = SD_CARD_PATH +File.separatorChar+ "2_new.mp4";
        String path_pattern = SD_CARD_PATH +File.separatorChar+ "2_%d.mp4";
        PatchUtils.patch(path_pattern, merge_path, 2);
        System.out.println("合并完成");
    }
}

6.注意添加权限,6.0动态申请

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
07.Android Studio下Ndk开发(使用fmod播放声音)
(创建于2017/12/28) 已实现 注意几点: 1.main下cpp文件夹放置c文件和相关头文件 2.main下JniLibs文件夹放置第三方so文件 3.
1092 0
【jar】JDK将单个的java文件打包为jar包,并引用到项目中使用【MD5加密】
========================================================================================================================= 后文心得附录:【实际操作使用过程中的使用心得】   1.
1111 0
03.Eclipse下Ndk开发(以文件加密为例模拟一下开发过程)
(创建于2017/12/2) 1.编写native方法 package com.example.ndk_file_encrpty; public class Cryptor { static{ System.
887 0
SNMP从入门到开发:进阶篇
管理信息库:MIB 我们要扩展mib首先必须清楚mib是如何定义的,用的什么语言,有哪些约定,遵循哪些规则等等。这些基本东西掌握过后,我们就可以很轻松的来写自己的mib文件了。 所谓管理信息库,或者MIB,就是所有代理进程包含的、并且能够被管理进程进行查询和设置的信息的集合,或者叫管理对象的集合,在RFC 1213 [McColghrie 和Rose 1991]中定义了MIB-II,即第二版的MIB库。
943 0
04.Eclipse下Ndk开发(以文件拆分合并为例模拟一下开发过程,参考文件加密的过程)
(创建于2017/12/6) 1.工具类PatchUtils package com.ren.ndk_file_patch; public class PatchUtils { static{ System.
825 0
SNMP从入门到开发:基础篇
SNMP协议入门 1、引言 基于TCP/IP的网络管理包含3个组成部分: 1) 一个管理信息库MIB(Management Information Base)。
926 0
android ndk开发之环境搭建
<div id="article_content" class="article_content"> <p><strong><span style="font-size:18px">一:Cygwin的下载与安装:</span></strong></p> <p><span style="white-space:pre"></span><span style="white-space:pr
1620 0
20.Eclipse下Ndk开发(pthread开启线程调用Java方法)
本项目最终的目的是在pthread线程中,调用Java一个工具类得到多个uuid,然后调用类中另一个方法弹出toast,实现在c中获取安卓上下文对象Context 编译native方法,生成头文件的一系列过程不再赘述,直接上代码,都在注释中 PosixUtils: package com.
979 0
10.Eclipse下Ndk开发(ffmpeg native 方式播放视频,万能解码(SurfaceView, 播放音频,)
(创建于2018/1/26) 遇到的问题 遇到一个很棘手的问题,在Eclipse上引入两个头文件报错 #include #include 右键->Porperties->C/C++General->Paths and Symbols中可以看到 987671.
1137 0
10.Eclipse下Ndk开发(ffmpeg解码)
(创建于2018/1/7) ffmpeg库简介: 4113515.png 解码流程图: 4062671.png 解码过程涉及到的函数 4191421.
883 0
+关注
黑夜路口
安卓高级工程师,目前任职于Wifi万能钥匙
152
文章
1
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载