httpで取得したデータをファイルへ保存する方法
続いて、前回利用したhttpパッケージを使ってサーバから取得した画像をファイルへ保存する場合を紹介します。
サーバからデータを取得し、そのデータをファイルに保存しておく場合はスマホアプリの場合多々あります。例えば、アプリを起動すると必ず、データチェックを行い、足りないデータをサーバからダウンロードするアプリをよく見かけるはずです。特にゲームでは一般的です。このようにする目的としては、初期のアプリサイズを小さくすることや、常に新しいコンテンツデータでアプリを実行できるようにするためです。
今回は、よりシンプルな用途であるサーバから取得した画像データをファイルに保存する実装例をリスト6に示します。これまでと違いデータを受信しながら、そのデータをファイルに保存しています。
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:http/http.dart' as http;
Future<void> saveHttpData() async{
var tmpDir = await getTemporaryDirectory();
var tmpId = new DateTime.now().millisecondsSinceEpoch;
var tmpFile = File('${tmpDir.path}/${tmpId}.png');
// (1) HTTPでデータをGETする処理
var client = http.Client();
var req = http.Request('GET',Uri.parse("http://192.168.1.1/chat/avatar/1.png"));
var res = await client.send(req);
// (2) 結果データをストリームとして取得する処理
res.stream.listen((value){
// (3) データを追記する処理
tmpFile.writeAsBytesSync(value,mode: FileMode.append);
}).onDone(() async{
var len = tmpFile.lengthSync();
print(" done bytes ... (${len}) -> ${tmpFile.path}");
// (4) HTTPの接続を切断する
client.close();
});
}
(1)ではhttpパッケージを使ってデータを取得する処理です。前回まではgetやpostというメソッドを使っていましたが、今回はより低レベルのメソッドであるsendメソッドを使います。
そして、(2)のようにレスポンスデータをストリームとしてデータを取得する毎に処理ができるようにします。取得したデータは(3)のようにwriteAsBytesSyncメソッドを使ってバイトデータと保存します。
ただし、今回のケースでは受診したデータをファイルに追加していく必要があるので、FileMode.appendを指定して書き込みます。そして、データの受信が完了した時点で(4)のようにhttpを切断します。
ここで気をつけなければいけないことは(3)での処理が同期型処理にする必要があるということです。もし、(3)での処理を非同期型処理にすると、ファイルの書き込みが終了する前に(4)でのhttp接続を切断してしまうことになります。
最後に
今回は、主なデータの保存方法において基本的な方法であるKey-Valueでの値の保存とファイルへの保存について紹介しました。
データが主にサーバ上にあり、オンラインが必須であるアプリケーションであれば、これらの二つの方法で十分、実用的なアプリケーションを作成することが可能です。
しかし、それではブラウザ上で動くアプリケーションと大きな違いがないということもあり、ネットに接続していない状態でも利用させたいという場合もあるでしょう。そのような場合によく利用するのが、今回紹介できなかった端末内で動作するデータベースを利用する方法です。
これまでの利用方法よりも少々複雑になりますが、今回紹介したデータ管理よりも高度な機能が実現できます。また、これらの方法を複数組み合わせて一つのデータとして扱う場合もあります。
