Android使用C(ndk)从资产文件夹中读取文本文件

时间:2022-11-21 17:28:39

I need to read text file from asset folder in android, by searching through internet I found that there is asset_manager api available from android 2.3 onwards. As I am targeting only tablet devices this is useful. But as I am not expert in C language I am not able to find any example on how to read/write files using file descriptor. I found many examples using FILE* (file pointers)

我需要从android中的资产文件夹中读取文本文件,通过在互联网上搜索,我发现有从android 2.3开始提供的asset_manager api。由于我只针对平板电脑设备,因此这很有用。但由于我不是C语言专家,我无法找到有关如何使用文件描述符读/写文件的任何示例。我发现很多使用FILE *的例子(文件指针)

My goal is to decrypt a js file from asset folder which is encrypted using C (for securing the code), as js code is visible if end user decompiled my apk. Because asset folder is inside zip file is it possible to do?

我的目标是解密资产文件夹中的js文件,该资源文件夹使用C加密(用于保护代码),因为如果最终用户反编译我的apk,则js代码可见。因为资产文件夹在zip文件里面是可以的吗?

3 个解决方案

#1


32  

Here is the code I used to read file from android assets folder using asset_manager ndk lib

这是我用来使用asset_manager ndk lib从android资源文件夹中读取文件的代码

    AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
    AAsset* asset = AAssetManager_open(mgr, (const char *) js, AASSET_MODE_UNKNOWN);
    if (NULL == asset) {
        __android_log_print(ANDROID_LOG_ERROR, NF_LOG_TAG, "_ASSET_NOT_FOUND_");
        return JNI_FALSE;
    }
    long size = AAsset_getLength(asset);
    char* buffer = (char*) malloc (sizeof(char)*size);
    AAsset_read (asset,buffer,size);
    __android_log_print(ANDROID_LOG_ERROR, NF_LOG_TAG, buffer);
    AAsset_close(asset);

Added following line to my Android.mk

在我的Android.mk中添加了以下行

# for native asset manager
LOCAL_LDLIBS    += -landroid

And don't forget the include in source file

并且不要忘记源文件中的include

#include <android/asset_manager.h>

#2


2  

Practically FILE* and 'int' descriptors are equivalent and fread/fwrite/fopen/fclose are the counterparts of open/close/read/write functions (the functions are not equivalent however, the latter are non-blocking).

实际上FILE *和'int'描述符是等价的,fread / fwrite / fopen / fclose是打开/关闭/读/写函数的对应物(函数不等效,但后者是非阻塞的)。

To get 'int' from 'FILE*' you can use

要从'FILE *'获得'int',你可以使用

int fileno(FILE* f);

in header and to do the inverse you can use fdopen()

在标题中并执行反转您可以使用fdopen()

FILE *fdopen(int fd, const char *mode);

So either replace everything using the FILE* to int or just take one of the samples and insert this conversion code before the file reading.

因此要么使用FILE *替换所有内容,要么只取一个样本并在文件读取之前插入此转换代码。

#3


2  

It's pretty similar to regular fread/fseek functions. Here's read function declaraton:

它与常规的fread / fseek功能非常相似。这是读函数声明:

ssize_t read(int fd, void *buf, size_t count);

It reads from fd file descriptor into buf buffer count bytes. If you think about fread, then instead of:

它从fd文件描述符读取到buf缓冲区计数字节。如果你考虑fread,那么而不是:

fread(buf, count, size, file);

you will call:

你会打电话给:

read(fd, buf, count*size);

And that's it. It is so simple.

就是这样。这很简单。

Seeking is also similar. Just look up the function declaration and read the argument names/description. It will be obvious.

寻求也是类似的。只需查看函数声明并读取参数名称/描述。很明显。

#1


32  

Here is the code I used to read file from android assets folder using asset_manager ndk lib

这是我用来使用asset_manager ndk lib从android资源文件夹中读取文件的代码

    AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
    AAsset* asset = AAssetManager_open(mgr, (const char *) js, AASSET_MODE_UNKNOWN);
    if (NULL == asset) {
        __android_log_print(ANDROID_LOG_ERROR, NF_LOG_TAG, "_ASSET_NOT_FOUND_");
        return JNI_FALSE;
    }
    long size = AAsset_getLength(asset);
    char* buffer = (char*) malloc (sizeof(char)*size);
    AAsset_read (asset,buffer,size);
    __android_log_print(ANDROID_LOG_ERROR, NF_LOG_TAG, buffer);
    AAsset_close(asset);

Added following line to my Android.mk

在我的Android.mk中添加了以下行

# for native asset manager
LOCAL_LDLIBS    += -landroid

And don't forget the include in source file

并且不要忘记源文件中的include

#include <android/asset_manager.h>

#2


2  

Practically FILE* and 'int' descriptors are equivalent and fread/fwrite/fopen/fclose are the counterparts of open/close/read/write functions (the functions are not equivalent however, the latter are non-blocking).

实际上FILE *和'int'描述符是等价的,fread / fwrite / fopen / fclose是打开/关闭/读/写函数的对应物(函数不等效,但后者是非阻塞的)。

To get 'int' from 'FILE*' you can use

要从'FILE *'获得'int',你可以使用

int fileno(FILE* f);

in header and to do the inverse you can use fdopen()

在标题中并执行反转您可以使用fdopen()

FILE *fdopen(int fd, const char *mode);

So either replace everything using the FILE* to int or just take one of the samples and insert this conversion code before the file reading.

因此要么使用FILE *替换所有内容,要么只取一个样本并在文件读取之前插入此转换代码。

#3


2  

It's pretty similar to regular fread/fseek functions. Here's read function declaraton:

它与常规的fread / fseek功能非常相似。这是读函数声明:

ssize_t read(int fd, void *buf, size_t count);

It reads from fd file descriptor into buf buffer count bytes. If you think about fread, then instead of:

它从fd文件描述符读取到buf缓冲区计数字节。如果你考虑fread,那么而不是:

fread(buf, count, size, file);

you will call:

你会打电话给:

read(fd, buf, count*size);

And that's it. It is so simple.

就是这样。这很简单。

Seeking is also similar. Just look up the function declaration and read the argument names/description. It will be obvious.

寻求也是类似的。只需查看函数声明并读取参数名称/描述。很明显。