Flutterでファイルの読み書きを動かしてみる

Flutterのファイル読み書きのサンプルソースがあるので、それを動作させてみる。

サンプルを動かすだけなので、公式を読んでもらえば同じことが出来ると思う。

https://flutter.dev/docs/cookbook/persistence/reading-writing-files

ココ見たら全部解決するよ！
って言ってしまえば、それまでなんだけど。

## 前提
- 当たり前だけどFlutterのテンプレートが動作する環境を用意する
  - まだなら、（せっかくなので）書いた記事あるから、読んで環境作ってみて
     - [Flutterの導入(1) ~for Windows10~ Android Studio と Flutter をインストールしよう](https://qiita.com/bonkoturyu/items/5ab3d756c24f5b8875a8)
     - [Flutterの導入(2) ~for Windows10~ Visual Studio Code をインストールしよう](https://qiita.com/bonkoturyu/items/93bbcfa9303ecda5227a)
     - [Flutter で Windows アプリをテンプレートから生成し、起動してみよう](https://qiita.com/bonkoturyu/items/4216ac49981ccf8a41b7)

## 前提が出来たら、テンプレから作ろう
[公式サンプル](https://flutter.dev/docs/cookbook/persistence/reading-writing-files)に書いてあるとおりにすればいいだけではあるんだけど。

- 今回は、Visual Studio Code でのやり方だけを説明するよ。
  - Android Studio の人は、テンプレート作成を自分の環境に合わせてね
  - 以下の環境をベースに説明していくよ
     - Flutter Pub 2.14.0-312.0.dev
     - Visual Studio Code 1.58.2
- やることは、これだけ。
  1. テンプレートからプロジェクトを生成する
  2. サンプルのソースをコピペする
     - サンプルページの一番下に Complete example があるからそれのコピペ
  3. 必要なパッケージをインポートする準備をする
     - pubspec.yaml の編集の話
  4. プロジェクトの更新をしてパッケージをインポートする
     - flutter pub get や flutter pub upgrade する話
  5. 実行してみる
     - 実行→終了→実行ってすると前のカウンタが保存されてるね、やったね！

## Visual Studio Code でテンプレートプロジェクトを作成
あんまり説明いらない気もするけど、一応書いておく。
必要なければ飛ばして。
1. Visual Studio Code を起動する
2. 表示 → コマンドパレット を起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194966/4fffa04d-43f8-b5d3-a6b8-d8b7e84316f6.png)
3. flutter ってコマンドパレットに入力して、 Flutter: New Application Project をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194966/65f7b17c-bdd8-f0de-a324-0f8f9970379c.png)
4. フォルダーの選択が出る。右下には Select a folder to create the project in って書いてあるから、プロジェクトを作成するフォルダを選ぶ。
今回はドキュメントを選択。（作るのは好きな場所でいい）
5. アプリの名前を決める。今回は file_io にしとく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194966/2bb6495a-4f11-7c82-bc4c-f6c14518f9e8.png)
6. 自動的に色々生成されるので待つ。
7. 生成されたら、表示 → ターミナル でターミナルを起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194966/b0c80cbc-ae2a-3204-e989-6ac7ef68759d.png)
8. 下側にターミナルが出るので、flutter run と入力して実行

```
Microsoft Windows [Version 10.0.19043.1110]
(c) Microsoft Corporation. All rights reserved.

C:\Users\hogehoge\Documents\file_io>flutter run
```

特にデバイスを繋いで無ければ、こんなのが出たりする。
ここは環境によるので、出てるのが違うかも。
Windows を有効にしてれば、↓ こうなる。

```
Multiple devices found:
Windows (desktop) • windows • windows-x64    • Microsoft Windows [Version 10.0.19043.1110]
Chrome (web)      • chrome  • web-javascript • Google Chrome 92.0.4515.131
Edge (web)        • edge    • web-javascript • Microsoft Edge 91.0.864.70 
[1]: Windows (windows)
[2]: Chrome (chrome)
[3]: Edge (edge)
Please choose one (To quit, press "q/Q"): 
```
ここで 1 を選ぶと、Windowsアプリとしてビルドして起動される。

```
Please choose one (To quit, press "q/Q"): 1
Launching lib\main.dart on Windows in debug mode...
Building Windows application...                                         
Syncing files to device Windows...              92ms
```
実行されると、ターミナルにはこんなの出てる。

```
Flutter run key commands.
r Hot reload.
R Hot restart.
h List all available interactive commands.
d Detach (terminate "flutter run" but leave application running).
c Clear the screen
q Quit (terminate the application on the device).

 Running with sound null safety 

An Observatory debugger and profiler on Windows is available at: http://127.0.0.1:57129/44as1fFdgrM=/
Activating Dart DevTools...                                      2,598ms
The Flutter DevTools debugger and profiler on Windows is available at: http://127.0.0.1:9101?uri=http://127.0.0.1:57129/44as1fFdgrM=/
```
実行画面は、↓ こう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194966/6358e368-fd11-d584-4ebe-27bb603e4212.png)
ターミナルをクリックして、 q を押すと、アプリが終了する。
（ターミナルにあった、 `q Quit (terminate the application on the device).` ってのは、これのこと）
これで、Flutterが動作する環境が整ったってこと。
どこかエラーになったり引っかかったなら、環境から見直す。

## サンプルのソースをコピペする
動かしてみないと分かりづらいので、
[公式サンプル](https://flutter.dev/docs/cookbook/persistence/reading-writing-files)にある、Complete example をコピペ。
コピーアイコンも右にあるから使うと良いと思う。

1. Complete example を丸ごとコピーする
2. さっき作ったプロジェクトの main.dart をクリックして開く
3. 選択 → すべて選択 する
4. 編集 → 貼り付け する

これで完成！だったら良かったんだけど。
何か赤くなって、あからさまにビルドが通らなくなってる。
これは、必要なパッケージが足りないよって教えてくれてる状態。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194966/6fc1d837-1e79-9e41-f4cd-a34baf9a423c.png)
なので、パッケージの追加をこれから行う。
今回でいうと、 path_provider っていうのが足りない。

## 必要なパッケージをインポートする準備をする
パッケージをどこからインポートするんだ？ってなったら。
`pubspec.yaml` っていうファイルを開いて編集する必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194966/e644e55f-f37e-4edc-b0d4-655e013b711e.png)
この yaml ファイルを開いて編集する。
編集する場所は、 dependencies: → flutter: のところ。
そこに `path_provider: ^2.0.2` を追加する。(2021/08/03 現在)
もっと新しいのがあったら、その時はVersionを新しくして。
書くとこんな感じ。↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194966/c7d32329-3e1f-b3c8-119a-7433198caf29.png)
これで、パッケージ設定は完了。

## プロジェクトの更新をしてパッケージをインポートする
Visual Studio Code が自動認識してインポートするから不要かも。
必要だったら、 `flutter pub get` と、 `flutter pub upgrade` してみて。

### 実行してみる……前にソースの修正
この時点で、まだ文字が赤くなってるとこがあると思う。
そう。`test\widget_test.dart` ってファイル。
さっき、Complete example から全部コピペしたでしょ？
これによって、実行するためのメインAppが変わっちゃったので、
このエラーが出てる。なので `test\widget_test.dart` を直す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194966/914789ea-76ae-d585-e0aa-f8c4b84dabbe.png)
ココに書いてある、MyApp っていうのが無いって怒られてる。
`lib\main.dart` を見直してみると、MaterialApp ってのに変わってる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194966/cf2e4b63-38d9-90fc-924a-cbc9e2893054.png)
なので、`test\widget_test.dart` の MyApp を MaterialApp に変更する。
これだけ。

## 実行してみる
1. ターミナルを開く
2. `flutter clear` と入力して実行
   - これは念の為。Hot Reload があるから、本来は不要
3. `flutter run` と入力して実行

```
Multiple devices found:
Windows (desktop) • windows • windows-x64    • Microsoft Windows [Version 10.0.19043.1110]
Chrome (web)      • chrome  • web-javascript • Google Chrome 92.0.4515.131
Edge (web)        • edge    • web-javascript • Microsoft Edge 91.0.864.70 
[1]: Windows (windows)
[2]: Chrome (chrome)
[3]: Edge (edge)
Please choose one (To quit, press "q/Q"): 
```
これが出るので、好きなデバイスを選ぶ。実行すると、↓こんなのが出る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194966/eab48c45-08c1-f0cc-032d-181ceac0141d.png)
＋をクリックすると、回数が増えていく。ソコはサンプルとおんなじ。
何回か、＋をクリックしたあとに、ターミナルで q を押下するか、
ウィンドウの右上の × で終了する。
終了したあと、ターミナルに、flutter run と入力して実行すると、
前にクリックした回数が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194966/d21b0126-6be7-8fe3-d19f-8f11563ac645.png)
保存場所は、ドキュメントフォルダ直下になっている。
デバッグ表示として見たいのであれば、
`class CounterStorage` の `_localFile` に debugPrint を追加したらいい。

```dart:main.dart
  Future<File> get _localFile async {
    final path = await _localPath;
    debugPrint('saved $path/counter.txt'); // こんな感じに書いとく
    return File('$path/counter.txt');
  }
```

ターミナルへの出力は、こんな感じに出てくる。
クリックするたびに出るのでわかりやすいかと。
パスのスラッシュとバックスラッシュが入り交じるけど気にしない。

```
flutter: saved C:\Users\hogehoge\Documents/counter.txt
```

もちろん、この counter.txt を削除すると、 0 からのカウントになる。

# 参考
- Read and write files
  - https://flutter.dev/docs/cookbook/persistence/reading-writing-files