.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のほうを使うほうが無難そうです。 (そのための仕組みだから当たり前ですが)