关于Android/IOS里边读取StreamingAsset目录 文件流
来源:互联网 发布:python的科学计数法 编辑:程序博客网 时间:2024/06/06 13:14
1.用Android接口来读取streamingAsset目录 可以提高效率,www方式效率不好 还耗内存。读取byte后直接CreateFromMemory 来创建bundle。其他模式还是CreateFromFile来创建效率更好,memory的方式耗内存,所以大文件还是要拷出来放在file目录 用 CreateFromFile来创建,IOS上全部用CreateFromFile。
public byte[] getFromAssetss(String fileName){ //android里边读取streamingAsset目录的文件
try {//得到资源中的Raw数据流
InputStream in = getResources().getAssets().open(fileName);
//得到数据的大小
int length = in.available();
byte [] buffer = new byte[length];
//读取数据
in.read(buffer);
//依test.txt的编码类型选择合适的编码,如果不调整会乱码
// res = EncodingUtils.getString(buffer, "BIG5");
//关闭
in.close();
return buffer;
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
关于文件读取速度 1 最快的是File目录下的File.readallbytes 其次用上边的接口读取StreamingAssets 目录 最后是WWW方式异步读取StreamingAssets 目录。
-----------------------------------------------------------------------------
上边是读取整个byte文件
2.下边方法是读StreamingAssets 文件流方式,读取的是byte的部分数据,注意的是native和java的交互的引用计数不得超过512 也就是一瞬间同时请求return的数据不能太多 不然内存的自动释放 反应不过来。解决的方法是把该段数据请求堆栈设为局部引用。在Unity里边如下使用:
for (int i=0; i<5000; i++) {
AndroidJNI.PushLocalFrame (0);
byte[] data = CenterGhome.getStreamFromAssetss ("test.x", 0, a1.Length);
AndroidJNI.PopLocalFrame (System.IntPtr.Zero);
}
------------------
// HashMap<String, InputStream> filemap = new HashMap<String, InputStream>();
// byte [] buffer = new byte[5*1024*1024];;
public byte [] getStreamFromAssetss(String fileName, int offset,int length){ //Android里边 not pathName
try {
/* InputStream in=null;
if(!filemap.containsKey(fileName))
{
in = getResources().getAssets().open(fileName);
filemap.put(fileName, in);
in.mark(10*1024*1024);//设置标记方便reset恢复原始位置
}
else
{
in = filemap.get(fileName);
}*/
InputStream in = getResources().getAssets().open(fileName);
//得到数据的大小
if(in!=null)
{
// int length0 = in.available();
byte [] buffer = new byte[length]; //这里new 好像比去unity里边copy data 快
// in.reset();//恢复原始位置
in.skip(offset);
int readCount = 0; // 已经成功读取的字节的个数
while (readCount < length)
{
readCount += in.read(buffer, readCount, length - readCount);//必须要慢慢读 不然可能读不完全。
}
in.close();
in=null;
return buffer;//一帧内请求不得超过512次数 。unity里边调用要设置局部引用AndroidJNI.PushLocalFrame (0);AndroidJNI.PopLocalFrame (System.IntPtr.Zero);不然超过512就要报错。
}
}
catch (Exception e)
{
Log.d("Unityjar","load Stream failed:" +fileName+e.getMessage());
return null;
}
return null;
}
-------------------------------------------IOS--------------------------------------------------------------
ios下边的目录可以使用FIle.Read 直接读取,但是StreamAsseting目录 文件流只能使用myStream = File.OpenRead(myPath); 来读。原因是FileMode.Open有读写权限 而StreamAsseting只有读的权限 所以 用FIle.Open会出错:Access to the path "/..Raw/4.page" is denied.
Note that on some platforms it is not possible to directly access the StreamingAssets folder because there is no file system access in the web platforms, and because it is compressed into the .apk file on Android. On those platforms, a url will be returned, which can be used using the WWW class.
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3.Native层通过JNI去读StreamingAsset资源:unity里边由于需要后台线程去加载资源,不能直接访问AndroidJni,然后就自己使用native层来读 使用.so库来加载:
dsnative.cpp
#include <jni.h>#include <sys/types.h>#include <stdlib.h>#include <android/asset_manager_jni.h>#include <android/asset_manager.h>#include <android/log.h>#include <stdio.h>#include <unistd.h>#include <dlfcn.h>#include <stdio.h>#include <fcntl.h>#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,"UnityNative",__VA_ARGS__) // 定义LOGD类型#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,"UnityNative",__VA_ARGS__)extern "C" {float add(float x, float y)//test{//LOGD("aaaaaaaaaaaaaa");return x + y;}static AAssetManager* mgr=NULL;void Java_com_meiyu_dungeonstriker_DSActivity_initreadFromAssets(JNIEnv* env,jclass tis,jobject assetManager){ LOGW("init_DSActivity_initreadFromAssets"); mgr = AAssetManager_fromJava(env, assetManager); if(mgr==NULL) { LOGW(" %s","AAssetManager==NULL"); return ; }}void getNativeStreamFromAssets(char* fileName,char* data, int offset,int length){ if(mgr==NULL) { LOGW("mgr is null "); return ; } AAsset* asset = AAssetManager_open(mgr, fileName,AASSET_MODE_UNKNOWN); if(asset==NULL) { LOGW("asset is null "); return ; } AAsset_seek(asset,offset,SEEK_SET); AAsset_read(asset, data, length); AAsset_close(asset);}JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved){LOGW("JNI_OnLoad");JNIEnv* env = NULL;#ifdef __cplusplusif (jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)#elseif ((*jvm)->GetEnv(jvm,(void**) &env, JNI_VERSION_1_4) != JNI_OK)#endif { return -1; }#ifdef __cplusplusjclass DSActivity = env->FindClass("com/meiyu/dungeonstriker/DSActivity");#elsejclass DSActivity = (*env)->FindClass(env,"com/meiyu/dungeonstriker/DSActivity");#endif if(DSActivity != NULL) {#ifdef __cplusplus jmethodID getSDPath = env->GetStaticMethodID( DSActivity, "getSDPath","()Ljava/lang/String;");#else jmethodID getSDPath = (*env)->GetStaticMethodID(env, DSActivity, "getSDPath","()Ljava/lang/String;");#endif jstring jstr = NULL;#ifdef __cplusplus jstr = (jstring)env->CallStaticObjectMethod(DSActivity, getSDPath);#else jstr = (jstring)(*env)->CallStaticObjectMethod(env, DSActivity, getSDPath);#endif const char* cstr = NULL;#ifdef __cplusplus cstr = env->GetStringUTFChars(jstr, 0);#else cstr = (*env)->GetStringUTFChars(env,jstr, 0);#endif if(cstr==NULL) { LOGW("11getSDPath=NULL"); } else { //LOGW("g_ResPath=%s",g_ResPath); //LOGW("cstr=%s",cstr); LOGW("11getSDPath OK"); } //strcpy(g_ResPath,cstr);///#ifdef __cplusplus env->ReleaseStringUTFChars(jstr,cstr);#else (*env)->ReleaseStringUTFChars(env,jstr, cstr);#endif //LOGW(cstr); //__android_log_print(ANDROID_LOG_WARN,"Unity",(const char*)cstr); } return JNI_VERSION_1_4;}JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *jvm, void *reserved){LOGW("JNI_OnUnload");return;}}
android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := dsnative
LOCAL_SRC_FILES := dsnative.cpp
LOCAL_SHARED_LIBRARIES += libandroid
LOCAL_LDLIBS += -llog -landroid -lEGL -lz
include $(BUILD_SHARED_LIBRARY)
application.mk
APP_ABI := armeabi armeabi-v7a x86
APP_STL:=stlport_static
java里边调用初始化接口:
public native void initreadFromAssets(AssetManager ass);
// Setup activity layout
@Override protected void onCreate (Bundle savedInstanceState)
{
System.loadLibrary("dsnative");
initreadFromAssets(getAssets());
}
c#里边使用native接口:
[DllImport("dsnative")]
private static extern void getNativeStreamFromAssets(string filename,byte[] data, int offset,int length);
byte[] data=new byte[1024*1024];
getNativeStreamFromAssets("test.x",data, a1.Length,b1.Length);
- 关于Android/IOS里边读取StreamingAsset目录 文件流
- 使用WWW方式读取StreamingAsset目录的图片
- java 读取属性文件里边的键值
- ios,android读取文件
- 如何读取IOS共享目录的文件
- android studio关于assets目录的创建、位置指向以及文件读取
- android读取assets目录底下文件
- Android 读取assets目录下的文件
- Android 读取 assets目录下的文件
- Android读取assets目录下所有文件
- Android 读取sdcard指定目录文件
- android JNI层读取assets目录文件
- Android读取res目录下xml目录下***.xml文件
- ios企业版证书怎样配置plist文件里边的url
- iOS 目录读取
- iOS文件管理,文件夹目录调取+缓存读取计算清除
- 关于怎么读取Maven项目resource目录下面的文件
- 布局文件里边 Android:background="@drawable/blue"会报错
- ActionBar
- JS核心笔记(一)
- Android design library(一)----------TabLayout
- Mysql只同步某些表
- 最小生成树-字典序最小
- 关于Android/IOS里边读取StreamingAsset目录 文件流
- 缩小窗口时CSS背景图出现右侧空白BUG的解决方法
- iOS开发之iOS8指纹解锁
- 查询分析器备份恢复数据库
- Linxu2.6的内核配置系统
- [Leetcode] [Database] Consecutive Numbers
- [Flashback]开启数据库闪回数据库功能
- 配置 FTP 服务
- fuser命令学习