【Unity】 アプリ内ストレージのデータ入出力

アプリ内ストレージのデータ入出力を行う簡単な方法。

ローカルストレージとか、単にデータとも言われたりしているが、
自分はひとまずローカルストレージと呼んでいる。

アプリ自身のファイルサイズを削減する為に、アプリにデータを含めずにこのローカルストレージに
データをインストールして、そこからロードして使う
という用途は良く使われている。

コンシューマゲームではモンハンで有名になったメディアインストール、あれと同じようなもの。

スマホの場合はサーバから圧縮されたデータをダウンロードし、
展開してローカルストレージにデータを出力し、ゲームはそこからデータをロードするやり方が主流になっている。
今後もデータサイズは必然的に増えていくだろうから、この手法を知っているのと知らないのとでは多少アドバンテージが出てくる。


Unityでそれっぽい事を実現するのは実に簡単だ。
ポイントはこの2つ。

①Application.persistentDataPath

②System.IO.File.WriteAllBytes, ReadAllBytes


Application.persistentDataPathは、persistent(永続性のある)なデータのパスという意味だから、
まぁとにかくローカルストレージへのパスという事だろう。

試しにパスを吐いてみたがこんな感じ。


・PC(Mac)

/Users/[ユーザ名]/Library/Caches/[CompanyName]/[ProductName]


・Android

/data/data/[Bundle Identifier]/files


・iOS

/var/mobile/Applications/[多分アプリ毎に暗号化されたフォルダ名]/Documents



そして、C#の標準ライブラリにあるSystem.IO.Fileクラスを使用して
このパスとやり取りをすればいいだけ。

簡単なサンプルコードを書いてみた。

void Start()
{
StartCoroutine( writeFileWithDownload() );
}

private IEnumerator writeFileWithDownload()
{
string url = "サーバのDLファイル名";

// サーバからファイルをDL
WWW web = new WWW( url );
yield return web;

if( web.error == null )
{
byte[] file_buf = web.bytes;
string file_name = Path.GetFileName( url ); // ファイル名を取得

// 出力先パス
string out_path = string.Format( "{0}/{1}", Application.persistentDataPath, file_name );
// ローカルストレージへ書き出し
File.WriteAllBytes( out_path, file_buf );
}
else{
Debug.LogError("download error.");
}
}


こうしてローカルストレージに保存したデータは File.ReadAllBytes で取得出来る。
1度ファイルを書きだすと、消さない限りストレージ内にずっと残るので、デバイスから見るアプリサイズはその分増える。

ちゃんと書き出せているかを調べたくなった場合、PCならすぐに見られるが、
実機の場合は少々めんどくさい。

iOSはiExprolerを使えばすぐに見られる。

が、Androidはroot化をしなければアクセス出来ない領域に保存されているので、
どうしても見たい場合はroot化するしか無いだろう。
root化した後に見る場合は、Androidのファイルマネージャ系アプリを使うと見られる。
もしくはadb shellで中に入って確認。

Androidのroot化はリスクがあるので注意。
root化しない場合は、アプリケーション管理メニューから該当アプリの「データ」の部分が
ローカルストレージデータに当たるはずなので、そのサイズで確認するというのも手である。


実はローカルストレージファイルの読み取りはWWWクラスでも出来る。

 string url = "file://" + Application.persistentDataPath + "/" + "ファイル名";
 
 WWW web = new WWW(url);
 yield return web;


が、これのメリットが分からない。

コルーチンになるから非同期リードになることぐらい?
File.WriteAllBytesとReadALlBytesの不安な所は、ファイルサイズが大きい場合にブロッキングしてしまう恐れがある。

実はまだC#のファイル入出力周りはこれとFileStreamぐらいしか触ったことがないので
非同期でローカルストレージファイルの入出力を行う最適な方法は知らない。

ん?待てよ...
今書いていて気付いたが、FileStreamに渡すパスを変えればひょっとして終了?w


また、試してみたら続きを書こうと思う。

[ 2013年09月14日 18:04:24 : Unity ]

カレンダー

プルダウン 降順 昇順 年別

06月 | 2020年07月 | 08月
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 -


全記事表示リンク

全ての記事を表示する

検索フォーム

リンク