SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Flutterで始めるモバイルアプリ開発

Flutterでデータを端末に保存する方法は?~Key-Valueでの値の保存とファイルへの保存~

Flutterで始めるモバイルアプリ開発 第23回

  • X ポスト
  • このエントリーをはてなブックマークに追加

ファイルにデータを保存する方法

 shared_preferencesパッケージでは非常に小さいデータを扱うための方法でしたが、データサイズが大きい場合に利用するのがファイルを使ったデータ管理です。

 事前に組み込みファイルとして用意できない画像データやメディアデータを、端末上に保存しておきたいことがよくあります。その場合には、取得したデータはファイルとして端末に保存しておきたくなります。または、アプリケーション特有の保存データを作成する場合などでも使える方法です。

 ただし、PCなどと異なりスマホなどではアプリ専用の保存フォルダが限定されているので、好きな場所にファイルを保存できるわけではありません。そのため、主に以下のような流れで処理をする必要があります。

  1. アプリケーションで利用可能なディレクトリ名を取得する。
  2. 保存する(またはロードする)ファイルのインスタンスを取得する。
  3. ファイルにデータを保存する。またはデータをロードする。

アプリケーションで利用できるディレクトリの取得

 アプリケーションで利用できるディレクトリ名を取得するには、path_providerパッケージを利用します。

 path_providerパッケージを利用する場合には、以下のようにpubspec.yamlに追加します。

[リスト3]path_providerパッケージの導入(pubspec.yamlの抜粋)
dependencies:
  : (省略)
  path_provider: ^2.0.11

 また、このパッケージを使って取得できるすべてのOS共通のフォルダ名は表1です。ここで示すディレクトリ以外にも端末SDカードなどの追加ストレージなどのOSもしくは端末固有のディクレトリ名も取得できるので、詳しくは、こちらを参照してください。

 また、スマホでよく利用するギャラリーに保存されている画像データなどにこちらのパッケージを使ってアクセスすることはできません。ギャラリーにアクセスするためには、利用者からのアクセス権限が必要になり、その方法はまた別の回で紹介します。

表1:環境に依存しない取得可能なディレクトリ一覧
フォルダ名 説明
Temporary 一時的なデータ保存領域です。起動していない時にシステムにより削除される可能性があるディレクトリです。
Application Support アプリケーションデータを保存するためのディレクトリです。
Application Documents 利用者が作成するファイルのためのディレクトリです。利用者が参照しても問題ないファイルを保存するディレクトリです。

 実際にこれらのディレクトリを取得するためのコードがリスト4です。

[リスト4]path_providerの利用例(path_provider.dart)
import 'dart:io';
import 'package:path_provider/path_provider.dart';

Future<void> pathProvider() async{

  // (1) ディレクトリの取得
  Directory dir1 = await getTemporaryDirectory();
  Directory dir2 = await getApplicationSupportDirectory();
  Directory dir3 = await getApplicationDocumentsDirectory();

  // (2) パスの取得
  print("getTemporaryDirectory : ${dir1.path}");
  print("getApplicationSupportDirectory : ${dir2.path}");
  print("getApplicationDocumentsDirectory : ${dir3.path}");
}
// -- (3) 出力例(Android) ---
I/flutter (15408): getTemporaryDirectory : /data/user/0/com.example.chatapp/cache
I/flutter (15408): getApplicationSupportDirectory : /data/user/0/com.example.chatapp/files
I/flutter (15408): getApplicationDocumentsDirectory : /data/user/0/com.example.chatapp/app_flutter

 各ディレクトリを取得するには、(1)のようにします。取得したディレクトリのパスを取得する場合には(2)のようにします。

 例えば、Androidの場合には取得したディレクトリパスは(3)のようになります。

 ただし、これらのパスは作成するアプリ名やパッケージ名、そしてOSによっても異なるので、これらのパスを指定して利用しないようにしてください。

ディレクトリとファイルを利用したデータの読み書き

 続いて、取得したディレクトリを使ってファイルに文字列データの保存/読込する例をリスト5に示します。

[リスト5]Directoryの作成とFileへの読み書き例(file.dart)
import 'dart:io';
import 'package:path_provider/path_provider.dart';

Future<void> createDirAndFile() async{
    Directory dir = await getApplicationSupportDirectory();

    //  (1) ディレクトリの作成
    Directory subdir = Directory("${dir.path}/subdir");

    // (2) 非同期型で記述する場合
    bool has = await subdir.exists();
    if(has){
      await subdir.create();
    }
    // (3) 同期で記述する場合
    if(!subdir.existsSync()){
      subdir.createSync();
    }

    // (4) ファイルへのデータ書き込み
    File file = File("${subdir.path}/sample.txt");
    file.writeAsString("Hello World");
    // file.writeAsStringSync("Hello World");
  }

  Future<void> readFile() async{
    Directory dir = await getApplicationSupportDirectory();

    File file = File("${dir.path}/subdir/sample.txt");
    // (5) ファイルの内容の読込
    String text = await file.readAsString();
    // String text = file.readAsStringSync();
    print("----- ${text} ----");
  }

 (1)ではgetApplicationSupportDirectory()で取得したディレクトリ内にサブディレクトリを作成しています。存在しないディレクトリにはファイルは作成できませんので、サブディレクトリが必要な場合にはファイルとして扱う前に作成しておく必要があります。

 そして、ディレクトリの存在を確認するには、(2)もしくは(3)のようにexists()もしくはexistsSync()を利用します。これらは処理を非同期的に行うか、もしくは同期的に処理を行うかで異なります。また、ディレクトリを作成するには、create()もしくはcreateSync()を利用します。こちらも同様に同期型と非同期型の処理があります。

 そして、ファイルへの文字列データの書き込みは(4)のように行い、データを読み込む場合には(5)のように行います。ファイル操作を行うメソッドにはこのように同期型と非同期型のメソッドがあります。

 例えば、ファイルやディレクトリの存在確認や作成であれば、UIを止めるほどのコストは通常かかりませんので、同期処理であっても問題ないケースが多いはずです。一方で、ファイルの書込や読込では扱うデータ量の大きさで問題が違うので、一般的には非同期型のメソッドを利用する方が問題ありません。

次のページ
httpで取得したデータをファイルへ保存する方法

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Flutterで始めるモバイルアプリ開発連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/16668 2022/10/27 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング