├── AndroidStreamingAssets.cs └── README.md /AndroidStreamingAssets.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using ICSharpCode.SharpZipLib.Zip; 5 | using ICSharpCode.SharpZipLib.Core; 6 | 7 | public static class AndroidStreamingAssets 8 | { 9 | private const string STREAMING_ASSETS_DIR = "assets/"; 10 | private const string STREAMING_ASSETS_INTERNAL_DATA_DIR = "assets/bin/"; 11 | private const string META_EXTENSION = ".meta"; 12 | 13 | private static string m_path = null; 14 | public static string Path 15 | { 16 | get 17 | { 18 | if( m_path == null ) 19 | Extract(); 20 | 21 | return m_path; 22 | } 23 | } 24 | 25 | public static void Extract() 26 | { 27 | #if !UNITY_EDITOR && UNITY_ANDROID 28 | string targetPath = Application.temporaryCachePath; 29 | string result = System.IO.Path.Combine( Application.temporaryCachePath, "assets" ); 30 | 31 | if( Directory.Exists( result ) ) 32 | Directory.Delete( result, true ); 33 | 34 | Directory.CreateDirectory( targetPath ); 35 | 36 | if( targetPath[targetPath.Length - 1] != '/' || targetPath[targetPath.Length - 1] != '\\' ) 37 | targetPath += '/'; 38 | 39 | HashSet createdDirectories = new HashSet(); 40 | 41 | ZipFile zf = null; 42 | try 43 | { 44 | using( FileStream fs = File.OpenRead( Application.dataPath ) ) 45 | { 46 | zf = new ZipFile( fs ); 47 | foreach( ZipEntry zipEntry in zf ) 48 | { 49 | if( !zipEntry.IsFile ) 50 | continue; 51 | 52 | string name = zipEntry.Name; 53 | if( name.StartsWith( STREAMING_ASSETS_DIR ) && !name.EndsWith( META_EXTENSION ) && !name.StartsWith( STREAMING_ASSETS_INTERNAL_DATA_DIR ) ) 54 | { 55 | string relativeDir = System.IO.Path.GetDirectoryName( name ); 56 | if( !createdDirectories.Contains( relativeDir ) ) 57 | { 58 | Directory.CreateDirectory( targetPath + relativeDir ); 59 | createdDirectories.Add( relativeDir ); 60 | } 61 | 62 | byte[] buffer = new byte[4096]; 63 | using( Stream zipStream = zf.GetInputStream( zipEntry ) ) 64 | using( FileStream streamWriter = File.Create( targetPath + name ) ) 65 | { 66 | StreamUtils.Copy( zipStream, streamWriter, buffer ); 67 | } 68 | } 69 | } 70 | } 71 | } 72 | finally 73 | { 74 | if( zf != null ) 75 | { 76 | zf.IsStreamOwner = true; 77 | zf.Close(); 78 | } 79 | } 80 | 81 | m_path = result; 82 | #else 83 | m_path = Application.streamingAssetsPath; 84 | #endif 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unity Android StreamingAssets 2 | Sometimes, you may want to use `File.ReadAllText`, `File.Exists` etc. functions on files that are located at `Application.streamingAssetsPath`. However, on Android platform, these files are located inside the application file (*.apk* or *.jar*, not sure) and can only be accessed via **WWW** class. 3 | 4 | This script extracts the contents of StreamingAssets to local file system (**Application.temporaryCachePath/assets/**, to be precise) using **SharpZibLib** library so that you can perform regular file operations on these files. 5 | 6 | - Use `AndroidStreamingAssets.Path` to access the root directory of the extracted StreamingAssets. This property internally calls the `AndroidStreamingAssets.Extract()` function the first time you access it. 7 | 8 | - `AndroidStreamingAssets.Extract()` function extracts the StreamingAssets from the application and can optionally be called manually to avoid any stutters when you first call *AndroidStreamingAssets.Path*. Be aware that each call to AndroidStreamingAssets.Extract() function extracts the StreamingAssets over and over again; so it is sufficient and recommended to call this function just once when your application starts. 9 | 10 | This script requires **SharpZipLib** to extract the StreamingAssets (you can just import the *.dll* file to your project): https://github.com/icsharpcode/SharpZipLib/releases 11 | --------------------------------------------------------------------------------