【Flutter】ファイルの出力と読込【日本語】

Flutterでのファイルの出力と読込を行ってみます。

初心者の私でも簡単に出来たので、その備忘録となります。

ファイルの入出力は出番が多い処理だと思いますので、しっかりと抑えていきたいですね。

他のプログラミングに関する記事はこちら

スポンサーリンク

前提

過去に作成した以下記事の「作成したものとソースコード」のソースコード全文を元に作成していきます。

入力フォームの実装

Flutterの入力フォームを実装していきます。 入力されたものを画面上に表示するというものを作ってみます。 他のプログラミングに関する記事はこちら スポンサーリンク [adcode] 前[…]

スポンサーリンク

今回試しに作ったもの

作ったもの

文字を入力して、それをファイル出力する

出力したファイルを読み取り、読み取った内容を画面上に表示させる

 

というアプリを作りました。

ソースコード

最終的なソースコードは以下の通りです(詳細は後述します)

main.dartとpubspec.yamlをいじってます。

import 'dart:async'; //非同期処理用ライブラリ
import 'dart:io';  //ファイル出力用ライブラリ
import 'package:path_provider/path_provider.dart'; //アプリがファイルを保存可能な場所を取得するライブラリ

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget { 
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'otameshi',
      home: Scaffold(
        appBar: AppBar(
          title: Text('OutputTest'),
        ),
        body: OutputTest(),
      ),
    );
  }
}

class OutputTest extends StatefulWidget{
  @override
  _OutputTestState createState() => new _OutputTestState();
}

class _OutputTestState extends State<OutputTest>{

  // 入力された内容を保持するコントローラ
  final outputController = TextEditingController();

  // 表示用の変数
  String inputText = "0回、出力しました";
  int inputNum = 0;

  // 「ファイルに出力する」が押されたときの処理
  void output(String s) async{
    setState(() {
      ++inputNum;
      inputText = "" + inputNum.toString() + "回、出力しました";
    });
    
    getFilePath().then((File file) { //thenの記述で非同期処理であるgetFilePath関数の処理を待っている
      file.writeAsString(s);
    });
  }

  //ファイルの読み込みと変数への格納処理
  void loadFile() async {
    setState(() {
      load().then((String value) {
        setState(() {
          inputText = value;
        });
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.start,
      children: <Widget>[
        // Column1
        Container(
          alignment: Alignment.center,
          child: Container(
            width: 300,
            height: 100,
            child: TextField(
              enabled: true, //活性or非活性
              maxLength: 10, //入力最大文字数
              style: TextStyle(color: Colors.red), //入力文字のスタイル
              obscureText: false, //trueでマスク(****表記)にする
              maxLines:1, //入力可能行数
              controller: outputController,
            ),
          )
        ),

        // Column2
        GestureDetector(
          onTap: () {
            output(outputController.text);
          },
          child: Text("ファイルに出力する"),
        ),

        // Column3
        GestureDetector(
          onTap: () {
            loadFile();
          },
          child: Text("ファイルを読み込む"),
        ),

        // Column4
        Text(inputText),

      ],
    );
  }
}

//テキストファイルを保存するパスを取得する
Future<File> getFilePath() async { //Future<T> 関数名 asyncで<T>クラスを扱いとする非同期処理をする関数。非同期処理は、実行されると、その終了を待たずに他の処理が実行されます。関数内に1つでも非同期処理が実行される場合は非同期関数となります。
  final directory = await getTemporaryDirectory(); //await はその処理が終わるまで待つということ
  debugPrint(directory.path);
  return File(directory.path + '/test.txt');
}

//テキストファイルの読み込み
Future<String> load() async {
  final file = await getFilePath();
  return file.readAsString();
}

 

name: myapp
description: A new Flutter project.
version: 1.0.0+1

environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  
  path_provider: any

  cupertino_icons: ^0.1.2

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true

スポンサーリンク

ファイル出力の方法

まずはじめに、ファイル出力する方法です。

 

ファイル出力するためにはまず、ファイル出力するために必要なライブラリを導入します。

※ライブラリの導入方法は過去に以下記事でまとめていますので、もしよろしければ参考にしてください

ライブラリの導入方法

Flutterも他プログラミング言語同様に色々なパッケージ(ライブラリ)が用意されています。 パッケージ(ライブラリ)を導入することで、簡単に色々な機能を使えるようになるので、とても便利です。 今回は、Flutterでパッケージ[…]

 

そして、必要なライブラリは以下の3つです。

import 'dart:async'; //非同期処理用ライブラリ
import 'dart:io';  //ファイル出力用ライブラリ
import 'package:path_provider/path_provider.dart'; //アプリがファイルを保存可能な場所を取得するライブラリ

 

上記3つのライブラリを導入するため、pubspec.yamlのdependenciesに「path_provider: any」を記述をします。

dependencies:
  flutter:
    sdk: flutter
  
  path_provider: any

  cupertino_icons: ^0.1.2

 

次に、main.dartに、Future<File>が返り値のgetFilePath関数を以下の通り作成します。

getFilePath関数は、保存先とするファイルパスを取得する関数です。

※ファイル名はとりあえず固定で「test.txt」にしてます

Future<File> getFilePath() async {
  final directory = await getTemporaryDirectory();
  return File(directory.path + '/test.txt');
}

ちなみにFutureとは、非同期を行うための関数です。

返り値の型は<>で括って指定します。

今回の場合はFile型を返す非同期の関数……ということですね。

 

ちなみにasyncとは、非同期の関数に付属する言葉です。

getFilePath()関数を非同期で動くようにしているわけですね。

ファイル出力を使う場合は非同期にしなければいけないようです。

 

ちなみにawaitとは、非同期とは逆でその処理が終わるまで待たせたいときに指定します。

今回はawaitに保存先のディレクトリを取得する関数を設定していますが、そうしないと保存先のディレクトリ情報を取得する前に次の処理が行われてしまい、エラーになります。

 

 

getFilePath関数を作成したら、今度はそれを利用し出力の記述を行います。

出力の記述は以下の通りです。

getFilePath().then((File file) {
  file.writeAsString(s);
});

ちなみにthenとは、awaitと同じ感じです。

getFilePath()は非同期で動く関数なので、ディレクトリとファイル名を取得する前にその先の処理に進んだら大変です。

なので、thenを指定してあげることでgetFilePath()の完了を待っているわけです。

getFilePath()で返ってきたFile型のオブジェクトは、File型のfileという名前で取得しています

 

最後に、file.writeAsString(s)で出力しています。

sには文字列が入ります。

ここで指定した文字列がファイルに出力されるというわけですね。

スポンサーリンク

ファイル読込の方法

ファイルの出力が出来れば、ファイルの読み込みは超簡単です。

 

まず、load関数を作成します。

Future<String> load() async {
  final file = await getFilePath();
  return file.readAsString();
}

getFilePath()で読込先のファイルをfileオブジェクトに格納し、readAsString()で読み込んでいるだけです。

これでload関数を呼び出せばファイルを読み込み、その中身を返してくれるようになります。

スポンサーリンク

まとめ

冒頭で記載した最終的なソースコードの内容をざっくりと説明すると、以下のような感じです。

冒頭で記載した最終的なソースコード(main.dart)と見比べて頂ければとおもいます。

 

・1~3行目で、必要なライブラリを取得しています(pubspec.yamlの更新も忘れずに行う必要があります)

・107~112行目で、出力先とするファイルパスを取得する関数を設定してます。

・114~118行目で、出力したファイルの中身を取得する関数(読み込むための関数)を設定してます。

・84~88行目で、「ファイルに出力する」をクリックしたときにoutput関数を呼び出しています。

・38~48行目で、output関数を設定しています。内容は入力されている文字を出力しているだけです。

・92~97行目で、「ファイルを読み込む」をクリックしたときにloadFile関数を呼び出しています。

・50~59行目で、出力されたファイル内容を読み取り、画面上に表示するための変数に結果を代入しています。

他のプログラミングに関する記事

プログラミングまとめ

プログラミングに関する記事です。 言語とかツールごとにまとめています。 スポンサーリンク [adcode] Flutter ・簡単導入~サンプルアプリのデバック起動まで ・文字の表示(重ねて[…]

IMG

スポンサーリンク