最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

unity 如何使用文件流讀取streamingassets下的資源

 更新時(shí)間:2021年04月13日 09:09:42   作者:此車先開(kāi)  
這篇文章主要介紹了unity 使用文件流讀取streamingassets下的資源操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

目的:讀取streamingassets下的文件中指定的一段字節(jié)

已知:文件中的起始位置,和需要讀取的長(zhǎng)度

1.android下讀取

1.1 不能直接使用C#的FileStream,讀取失敗

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

報(bào)錯(cuò):

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交互

主要過(guò)程:

Java

public class XXXPlugin extends UnityPlayerNativeActivity {
    protected AssetManager assetManager;
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		assetManager = getAssets();
    }
 
	//返回字節(jié)數(shù)組
	public byte[] LoadBytes(String path,int offset,int len)
	{
         //可以緩存起來(lái),不需每次都o(jì)pen
         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的可靠性,每次調(diào)用不一定能返回正確長(zhǎng)度,可能需多次調(diào)用。

參考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分配內(nèi)存。

1.3 更靈活的方法,使用JNI,可以從C#傳遞指針到C++

在Android Studio中生成庫(kù)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 __cplusplus
extern "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.java
public class XXXPlugin extends UnityPlayerNativeActivity {
    static{
        System.loadLibrary("NativeLib");
    }
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  mainActivity = this;
  
  
        //設(shè)置AssetManager, C++中要使用
  NativeHelper.SetAssetManager(getAssets());
   }
 
}
 
//NativeHelper.java
public 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只有讀的權(quán)限,用OpenRead

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

補(bǔ)充:unity中 在移動(dòng)平臺(tái)各種讀寫(xiě)文件夾存路徑整理 如 StreamingAssets 等文件夾 各個(gè)路徑在各種平臺(tái)的文件路徑

1:Resources 文件夾 少用

//資源卸載
    /*
     *  Resources.UnloadAsset(obj):卸載非 GameObject類型的資源,會(huì)將內(nèi)存中已加載資源及其克隆體卸載。
        Destroy(obj):僅用于卸載GameObject類型的資源的克隆體。
        DestroyImmediately(obj):卸載GameObject類型的資源,會(huì)將內(nèi)存中已加載資源及其克隆體卸載,但該方法只能用在非編輯模式下,否則會(huì)報(bào)錯(cuò)提示改為DestroyImmediately(obj, true),然而編輯模式下使用該函數(shù)會(huì)連文件夾里的原始Asset一并刪除。
     */

2:StreamingAssets

在移動(dòng)端也是只可讀的不能寫(xiě)入數(shù)據(jù) 主要用來(lái)存放二進(jìn)制文件。

 //安卓下這兩個(gè)文件夾路徑相同 
    //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()
    {
        //安卓平臺(tái) 加文件名
#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

這個(gè)目錄可讀可寫(xiě) 一般存本地關(guān)卡等

用于存檔 直接使用 打包之前是沒(méi)有這個(gè)目錄的,直到應(yīng)用程序在手機(jī)上安裝完畢才有這個(gè)目錄。

該文件存在手機(jī)沙盒中,因?yàn)椴荒苤苯哟娣盼募?/h3>

1.通過(guò)服務(wù)器直接下載保存到該位置,也可以通過(guò)Md5碼比對(duì)下載更新新的資源

2.沒(méi)有服務(wù)器的,只有間接通過(guò)文件流的方式從本地讀取并寫(xiě)入Application.persistentDataPath文件下,然后再通過(guò)

Application.persistentDataPath來(lái)讀取操作。

注:在Pc/Mac電腦 以及Android跟Ipad、ipone都可對(duì)文件進(jìn)行任意操作,另外在IOS上該目錄下的東西可以被iCloud自動(dòng)備份。

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

對(duì)應(yīng)存儲(chǔ)路徑

Windows應(yīng)用商店應(yīng)用程序:

application.persistentdatapath指向%userprofile%\appdata\local\packages\<productName>\localstate

ios:application.persistentdatapath指向/var/mobile/containers/data/application/<guid>/documents

android:application.persistentdatapath指向大多數(shù)設(shè)備上的/storage/emulated/0/android/data/<packagename>/文件(有些舊手機(jī)可能指向SD卡上的位置,如果存在),該路徑使用android.content.context.getexternalfilesdir解析

4:Application.temporaryCachePath

來(lái)操作文件 同上但是 此屬性用于返回一個(gè)臨時(shí)數(shù)據(jù)的緩存目錄(不會(huì)備份并且清空緩存會(huì)清掉)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • C# Base64編碼函數(shù)

    C# Base64編碼函數(shù)

    Base64編碼的思想是是采用64個(gè)基本的ASCII碼字符對(duì)數(shù)據(jù)進(jìn)行重新編碼。它將需要編碼的數(shù)據(jù)拆分成字節(jié)數(shù)組。
    2009-06-06
  • C#中的Explicit和Implicit詳情

    C#中的Explicit和Implicit詳情

    Implicit提高了代碼的可讀性,但程序員需要自己保證轉(zhuǎn)換不引發(fā)異常且不丟失信息、Explicit可阻止編譯器靜默調(diào)用可能產(chǎn)生意外后果的轉(zhuǎn)換操作。前者更易于使用,后者能向閱讀代碼的每個(gè)人清楚地指示您要轉(zhuǎn)換類型,下面就和小編來(lái)一起學(xué)習(xí)吧
    2021-09-09
  • C# Distinct和重寫(xiě)IEqualityComparer時(shí)要知道的二三事

    C# Distinct和重寫(xiě)IEqualityComparer時(shí)要知道的二三事

    這篇文章主要給大家介紹了關(guān)于C# Distinct和重寫(xiě)IEqualityComparer時(shí)要知道的二三事,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • C#委托與事件原理及實(shí)例解析

    C#委托與事件原理及實(shí)例解析

    這篇文章主要介紹了C#委托與事件原理及實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-12-12
  • C# 郵件發(fā)送和接收實(shí)現(xiàn)代碼

    C# 郵件發(fā)送和接收實(shí)現(xiàn)代碼

    這兩個(gè)方法很容易理解,只實(shí)現(xiàn)了最基本的功能,如果需要可以查看源代碼獲取更多信息。
    2009-07-07
  • C#反射實(shí)現(xiàn)插件式開(kāi)發(fā)的過(guò)程詳解

    C#反射實(shí)現(xiàn)插件式開(kāi)發(fā)的過(guò)程詳解

    插件式架構(gòu),一種全新的、開(kāi)放性的、高擴(kuò)展性的架構(gòu)體系,插件式架構(gòu)設(shè)計(jì)好處很多,把擴(kuò)展功能從框架中剝離出來(lái),降低了框架的復(fù)雜度,讓框架更容易實(shí)現(xiàn),這篇文章主要介紹了C#反射實(shí)現(xiàn)插件式開(kāi)發(fā),需要的朋友可以參考下
    2023-09-09
  • C#連接SQL數(shù)據(jù)庫(kù)和查詢數(shù)據(jù)功能的操作技巧

    C#連接SQL數(shù)據(jù)庫(kù)和查詢數(shù)據(jù)功能的操作技巧

    本文給大家分享C#連接SQL數(shù)據(jù)庫(kù)和查詢數(shù)據(jù)功能的操作技巧,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-05-05
  • WPF實(shí)現(xiàn)能自由改變形狀的四邊形和六邊形

    WPF實(shí)現(xiàn)能自由改變形狀的四邊形和六邊形

    這篇文章主要為大家詳細(xì)介紹了WPF如何實(shí)現(xiàn)能自由改變形狀的四邊形和六邊形,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-03-03
  • c#幾種數(shù)據(jù)庫(kù)的大數(shù)據(jù)批量插入(SqlServer、Oracle、SQLite和MySql)

    c#幾種數(shù)據(jù)庫(kù)的大數(shù)據(jù)批量插入(SqlServer、Oracle、SQLite和MySql)

    這篇文章主要介紹了c#幾種數(shù)據(jù)庫(kù)的大數(shù)據(jù)批量插入(SqlServer、Oracle、SQLite和MySql),需要的朋友可以了解一下。
    2016-11-11
  • C#中Abstract方法和Virtual方法的區(qū)別

    C#中Abstract方法和Virtual方法的區(qū)別

    這篇文章介紹了C#中Abstract方法和Virtual方法的區(qū)別,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04

最新評(píng)論

许昌县| 桂东县| 宁津县| 饶河县| 凤城市| 那曲县| 永兴县| 日照市| 冀州市| 阜宁县| 什邡市| 曲水县| 祁连县| 莎车县| 汉阴县| 保靖县| 红桥区| 中阳县| 雷山县| 申扎县| 镇江市| 虹口区| 台中县| 耒阳市| 台南县| 班戈县| 北流市| 安塞县| 恭城| 樟树市| 徐水县| 新乡县| 石屏县| 延长县| 平阴县| 峡江县| 繁昌县| 于田县| 平顶山市| 岫岩| 常宁市|