しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

【Kotlin】res/rawフォルダとassetsフォルダの動作を見る

res/rawフォルダとassetsフォルダの違いが気になったので動作を見てみました。

公式ドキュメントの記述は下の通りです。
どちらも未加工のもの(おそらくtxtファイルなど)を入れるためのフォルダになります。
res/rawだとリソースIDでアクセスできるけどassetsだとアクセスできないという違いのようです。

未加工の形式で保存する任意のファイル。このリソースを未加工の InputStream で開くには、リソース ID(R.raw.filename)を指定して Resources.openRawResource() を呼び出します。

ただし、元のファイル名とファイル階層にアクセスする必要がある場合は、リソースの一部を res/raw/ ではなく assets/ ディレクトリに保存することもできます。assets/ に保存されたファイルにはリソース ID が付けられません。そのため、このファイルは AssetManager を使用する場合にだけ読み取ることができます。

アプリのリソースの概要  |  Android デベロッパー  |  Android Developers

それでは上記を実際に試してみようと思います。

まずは新規プロジェクトを作成してres/rawフォルダにhello.txtを入れます。
hello.txtの中身は下の通りです。

Hello world

続いてそのファイルにアクセスします。
Activityからのアクセス方法は下の通りです。
openRawResourceを呼ぶことでInputStreamを取得できます。

resources.openRawResource(R.raw.hello)

hello.txtの中身の取得方法は下の通りです。
InputStreamからInputStreamReaderを作って中身を取り出しています。

resources.openRawResource(R.raw.hello).use { input ->
    val text = InputStreamReader(input).use { it.readText() }
    Log.d("test", text) // → Hello world
}

次はassetsフォルダのデータ取得をしていきます。
まずはresフォルダと同じ階層にassetsフォルダを配置します。
配置するとAndroidStudio上では下のように表示されます。
これをassetなど別の名前にするとAndroidStudio上では見れません。

assetsには下のような内容のhello2.txtを配置します。

Hello world2

Activityからのアクセスは下のように行います。
ファイル名を文字列で指定するので動的なファイル指定などに便利そうです。
ファイル名を間違えた場合はFileNotFoundExceptionになるので注意が必要です。

assets.open("hello2.txt").use { input ->
    val text = InputStreamReader(input).use { it.readText() }
    Log.d("test", text) // → Hello world2
}

一応res/rawも下のようにすれば文字列からリソース取得可能です。

val resourceId = resources.getIdentifier("hello", "raw", packageName)
resources.openRawResource(resourceId).use { input ->
    val text = InputStreamReader(input).use { it.readText() }
    Log.d("test", text) // → Hello world
}

assetsは下のように中にフォルダを入れれるというメリットがあります。
res/rawの場合は中にフォルダを作っても認識されません。