滅入るんるん

何か書きます

.NET Standardでアプリケーションデータを保存するにはどうしたらいいんだろうっていう話

.NET Standardでは着々とAPIの共通化が行われ、PCLを使わなくてもある程度のことまでは .NET Standardで完結し始めてきました。
そこで、.NET Standardでアプリケーションデータを保存する際はどうしたらいいか手抜きながらに調べてみたのでメモとして書いておきます。

Environment.GetFolderPathとIsolatedStorageFile

Environment.GetFolderPathは単純に環境のFolderPathを取得するもので、IsolatedStorageFileはアプリケーションやアセンブリ単位で他のプログラムから分離するストレージのようです(詳しくは知らない)。

今回はそれっぽい領域の以下の4つを調べました。

  • Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData)
  • Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData)
  • IsolatedStorageFile.GetUserStoreForApplication()
  • IsolatedStorageFile.GetUserStoreForAssembly()

Environment.GetFolderPathに関してはアプリケーションデータを保存する領域以外にもDocumentsフォルダーとかも取得できます。
IsolatedStorageFileに関しては(Xamarin.Formsのコード覗いた感じ)enumで属性をOR指定して取得する場合もあるみたいですが、手抜きしたいので、それっぽいメソッドを使ってます。

調査

今回調査したのはXamarin.Android, UWP, Console Application(Windows)です。

IsolatedStorageFileに関してはPathを直接取得することはできないので、リフレクション使って確認します。

UWP, Console Application(Windows)の場合:

        private string isolatedPath(IsolatedStorageFile isolatedStorageFile)
        {
            var type = typeof(IsolatedStorageFile);
            var property = type.GetProperty("RootDirectory", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty);
            return property?.GetValue(isolatedStorageFile)?.ToString() ?? "null get";
        }

Xamarin.Androidの場合:

        private string isolatedPath(IsolatedStorageFile isolatedStorageFile)
        {
            var type = typeof(IsolatedStorageFile);
            var property = type.GetProperty("Root", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty);
            return property?.GetValue(isolatedStorageFile)?.ToString() ?? "null get";
        }

結果

Xamarin.Android

方法 パス
SpecialFolder.ApplicationData /data/user/0/{package}/files/.config
SpecialFolder.LocalApplicationData /data/user/0/{package}/files/.local.share
IsolatedStorageFile.GetUserStoreForApplication /data/user/0/{package}/files/.config/.isolated-storage
IsolatedStorageFile.GetUserStoreForAssembly /data/user/0/{package}/files/.config/.isolated-storage

UWP

方法 パス
SpecialFolder.ApplicationData C:\Users\{user}\AppData\Roaming
SpecialFolder.LocalApplicationData C:\Users\{user}\AppData\Local\Packages\{package}\LocalState
IsolatedStorageFile.GetUserStoreForApplication C:\Users\{user}\AppData\Local\Packages\{package}\IsolatedStorage\{url}\AppFiles\
IsolatedStorageFile.GetUserStoreForAssembly C:\Users\{user}\AppData\Local\Packages\{package}\IsolatedStorage\{url}\AssemFiles\

Console Application(Windows)

方法 パス
SpecialFolder.ApplicationData C:\Users\{user}\AppData\Roaming
SpecialFolder.LocalApplicationData C:\Users\{user}\AppData\Local
IsolatedStorageFile.GetUserStoreForApplication C:\Users\{user}\AppData\Local\IsolatedStorage\{文字列}\{文字列}\{url}\AppFiles\
IsolatedStorageFile.GetUserStoreForAssembly C:\Users\{user}\AppData\Local\IsolatedStorage\{文字列}\{文字列}\{url}\AssemFiles\

{文字列}にはよくわからない文字列が入ってました。
{url}にはURLそのものが入っているわけではなく、Url.から始まる文字列(不明)が入っていました。

SpecialFolder.ApplicationData・SpecialFolder.LocalApplicationDataともに環境によってPackage情報が入っていたり入っていなかったりするようなので、IsolatedStorageFileのほうを使うほうが無難そうです。
(そのための仕組みだから当たり前ですが)