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

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: (创建于2017/12/6)1.工具类PatchUtilspackage 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"/>
相关文章
|
3月前
|
数据安全/隐私保护 Python
用python对文件内容进行加密的2种方式
这篇文章介绍了使用Python对文件内容进行加密的两种方式:利用`cryptography`库的Fernet对称加密和使用`rsa`库进行RSA非对称加密。
74 6
|
2月前
|
安全 Linux 数据安全/隐私保护
python知识点100篇系列(15)-加密python源代码为pyd文件
【10月更文挑战第5天】为了保护Python源码不被查看,可将其编译成二进制文件(Windows下为.pyd,Linux下为.so)。以Python3.8为例,通过Cython工具,先写好Python代码并加入`# cython: language_level=3`指令,安装easycython库后,使用`easycython *.py`命令编译源文件,最终生成.pyd文件供直接导入使用。
python知识点100篇系列(15)-加密python源代码为pyd文件
|
2月前
|
数据安全/隐私保护 Python
Zipfile学习笔记(二)::通过zipfile模块暴力破解加密的压缩文件
如何使用Python的zipfile模块生成密码表并尝试暴力破解加密的ZIP压缩文件。
44 1
Zipfile学习笔记(二)::通过zipfile模块暴力破解加密的压缩文件
|
2月前
|
NoSQL Java Redis
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
这篇文章介绍了如何使用Spring Boot整合Apache Shiro框架进行后端开发,包括认证和授权流程,并使用Redis存储Token以及MD5加密用户密码。
36 0
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
|
3月前
|
人工智能 IDE 开发工具
Python实行任意文件的加密—解密
Python实行任意文件的加密—解密
31 2
|
3月前
|
人工智能 IDE 开发工具
Python实行任意文件的加密—解密
Python实行任意文件的加密—解密
51 1
|
2月前
|
IDE 开发工具 数据安全/隐私保护
Python编程实现批量md5加密pdf文件
Python编程实现批量md5加密pdf文件
39 0
|
4月前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享安卓与iOS开发中的线程管理比较
【8月更文挑战第30天】本文将探讨网络安全与信息安全的重要性,并分享关于网络安全漏洞、加密技术和安全意识的知识。我们将了解常见的网络攻击类型和防御策略,以及如何通过加密技术和提高安全意识来保护个人和组织的信息安全。
|
6天前
|
存储 SQL 安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将介绍网络安全的重要性,分析常见的网络安全漏洞及其危害,探讨加密技术在保障网络安全中的作用,并强调提高安全意识的必要性。通过本文的学习,读者将了解网络安全的基本概念和应对策略,提升个人和组织的网络安全防护能力。
|
7天前
|
SQL 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将从网络安全漏洞、加密技术和安全意识三个方面进行探讨,旨在提高读者对网络安全的认识和防范能力。通过分析常见的网络安全漏洞,介绍加密技术的基本原理和应用,以及强调安全意识的重要性,帮助读者更好地保护自己的网络信息安全。
24 10

推荐镜像

更多