文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

unity怎么使用文件流读取streamingassets下的资源

2023-06-14 12:10

关注

这篇文章将为大家详细讲解有关unity怎么使用文件流读取streamingassets下的资源,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

目的:读取streamingassets下的文件中指定的一段字节

已知:文件中的起始位置,和需要读取的长度

1.android下读取

1.1 不能直接使用C#的FileStream,读取失败

var buffer = new byte[size];FileStream stream = File.OpenRead(path);stream.Read(buffer , pos, size);

报错:

IsolatedStorageException: Could not find a part of the path "/jar:file:/data/app/com.xxx.xxxx-1/base.apk!/assets/xxx.pack".

1.2 可以使用Unity原生接口与Android交互

主要过程:

Java

public class XXXPlugin extends UnityPlayerNativeActivity {    protected AssetManager assetManager;protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);assetManager = getAssets();    } //返回字节数组public byte[] LoadBytes(String path,int offset,int len){         //可以缓存起来,不需每次都open         InputStream inputStream = assetManager.open(path);         try {                 byte buf[] = new byte[len];                 inputStream.reset();                                 //注意skip、read的可靠性                 inputStream.skip(offset);                 inputStream.read(buf,0,len)                  inputStream.close();                 return buf;    } catch (IOException e) {Log.v ("unity", e.getMessage());}return null;} }

注意skip、read的可靠性,每次调用不一定能返回正确长度,可能需多次调用。

参考how-does-the-skip-method-in-inputstream-work

C#:

public static byte[] read_streamingpath_bytes(string path,IntPtr ptr, int pos, int size)             {                using (AndroidJavaClass cls = new AndroidJavaClass("com.XXX.XXXPlugin";) )                 {                   AndroidJavaObject  m_AndroidJavaObject = cls.GetStatic<AndroidJavaObject>("mainActivity");                     byte[] s = m_AndroidJavaObject.Call<byte[]>("LoadBytes", path, pos, size);                     return s;                }                return null;            }

这种方法是在Java分配内存。

1.3 更灵活的方法,使用JNI,可以从C#传递指针到C++

在Android Studio中生成库libNativeLib.so文件,参考NativeReadBytes

C++

#include "com_XXX_NativeHelper.h"#include <android/asset_manager_jni.h>#include <android/asset_manager.h>#include <string>#include <jni.h>#include <stdint.h> #ifdef __cplusplusextern "C" {#endif static AAssetManager *assetManager = nullptr; JNIEXPORT void JNICALL Java_com_XXX_NativeHelper_SetAssetManager        (JNIEnv *env, jobject jobj, jobject jassetManager) {    assetManager = AAssetManager_fromJava(env, jassetManager);} JNIEXPORT int32_t JNICALL ReadAssetsBytesWithOffset(uint32_t pathKey, char* fileName, unsigned char** result, int32_t offset, int32_t length){    if(assetManager == nullptr){        return -1;    }    AAsset* asset = asset = AAssetManager_open(assetManager, fileName, AASSET_MODE_UNKNOWN);    if(asset == nullptr){        return -1;    }    off_t size = AAsset_getLength(asset);    if(size > 0){        try {            AAsset_seek(asset, offset, SEEK_SET);            AAsset_read(asset, *result, length);        }catch (std::bad_alloc){            *result = nullptr;            return -1;        }    }    AAsset_close(asset);    return (int32_t)length;}#ifdef __cplusplus}#endif

Java

//XXXPlugin.javapublic class XXXPlugin extends UnityPlayerNativeActivity {    static{        System.loadLibrary("NativeLib");    } @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  mainActivity = this;            //设置AssetManager, C++中要使用  NativeHelper.SetAssetManager(getAssets());   } } //NativeHelper.javapublic class NativeHelper {    public static native void SetAssetManager(AssetManager assetManager);}

C#

 public class ReadNativeByte    { #if UNITY_ANDROID        [DllImport("NativeLib")]        public static extern int ReadAssetsBytesWithOffset(uint pathKey,string name, ref IntPtr ptr, int offset, int length);#endif    }

2.IOS下读取

可以直接在C#下读取,StreamAsseting只有读的权限,用OpenRead

byte[] bytes = new byte[len];FileStream stream = File.OpenRead(path);stream.Seek(offset, SeekOrigin.Begin);stream.Read(bytes, 0, len);

补充:unity中 在移动平台各种读写文件夹存路径整理 如 StreamingAssets 等文件夹 各个路径在各种平台的文件路径

1:Resources 文件夹 少用

unity怎么使用文件流读取streamingassets下的资源

//资源卸载    

2:StreamingAssets

在移动端也是只可读的不能写入数据 主要用来存放二进制文件。

 //安卓下这两个文件夹路径相同     //Application.streamingAssetsPath = jar:file:///data/app/com.xxx.xxx-1.apk!/assets/  == "jar:file://"+Application.dataPath+"!assets/"    //Application.dataPath+"!assets/" = /data/app/com.xxx.xxx-1.apk!assets/    //Ios下    //Application.dataPath + "/Raw/" == @"file:///" + Application.streamingAssetsPath + "/"    //Editor WIN     //@"file:///" + Application.streamingAssetsPath + "/"    //"file:///" + Application.dataPath + "/StreamingAssets" + "/"
private string path = string.Empty;    public string GetSAPath()    {        //安卓平台 加文件名#if UNITY_ANDROID && !UNITY_EDITOR        path =  Application.streamingAssetsPath + "/"#elif UNITY_IPHONE && !UNITY_EDITOR        path = @"file:///" + Application.streamingAssetsPath + "/";#elif UNITY_STANDLONE_WIN||UNITY_EDITOR       path =  @"file:///" + Application.streamingAssetsPath + "/";#endif        return path;    }

3:Application.persistentDataPath

这个目录可读可写 一般存本地关卡等

用于存档 直接使用 打包之前是没有这个目录的,直到应用程序在手机上安装完毕才有这个目录。

该文件存在手机沙盒中,因为不能直接存放文件,

通过服务器直接下载保存到该位置,也可以通过Md5码比对下载更新新的资源

没有服务器的,只有间接通过文件流的方式从本地读取并写入Application.persistentDataPath文件下,然后再通过

Application.persistentDataPath来读取操作。

注:在Pc/Mac电脑 以及Android跟Ipad、ipone都可对文件进行任意操作,另外在IOS上该目录下的东西可以被iCloud自动备份。

Application.persistentDataPath + "/tempDic", "testXml"

对应存储路径

Windows应用商店应用程序:

application.persistentdatapath指向%userprofile%\appdata\local\packages\<productName>\localstateios:application.persistentdatapath指向/var/mobile/containers/data/application/<guid>/documents

android:application.persistentdatapath指向大多数设备上的/storage/emulated/0/android/data/<packagename>/文件(有些旧手机可能指向SD卡上的位置,如果存在),该路径使用android.content.context.getexternalfilesdir解析

关于“unity怎么使用文件流读取streamingassets下的资源”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯