50 lines
1.7 KiB
Dart
50 lines
1.7 KiB
Dart
import 'dart:io';
|
|
import 'dart:convert';
|
|
|
|
import 'snapshot_store.dart';
|
|
import '../domain/app_snapshot.dart';
|
|
|
|
class FileSnapshotStore extends SnapshotStore {
|
|
FileSnapshotStore(this.directory);
|
|
final Directory directory;
|
|
File get _file => File('${directory.path}/hepan_snapshot.json');
|
|
File get _backup => File('${directory.path}/hepan_snapshot.bak');
|
|
Future<AppSnapshot> _read(File file) async {
|
|
final value = jsonDecode(await file.readAsString());
|
|
if (value is! Map<String, dynamic>) throw const FormatException('保存文件损坏');
|
|
return AppSnapshot.fromJson(value);
|
|
}
|
|
|
|
@override
|
|
Future<AppSnapshot?> load() async =>
|
|
await _file.exists() ? await _read(_file) : null;
|
|
@override
|
|
Future<void> save(AppSnapshot snapshot) async {
|
|
await directory.create(recursive: true);
|
|
final text = jsonEncode(snapshot.toJson());
|
|
// Validate before touching the last successfully saved version.
|
|
AppSnapshot.fromJson(jsonDecode(text) as Map<String, dynamic>);
|
|
if (await _file.exists()) {
|
|
try {
|
|
await _read(_file);
|
|
await _file.copy(_backup.path);
|
|
} on FormatException {
|
|
/* Keep an existing valid backup. */
|
|
}
|
|
}
|
|
final temporary = File('${_file.path}.tmp');
|
|
await temporary.writeAsString(text, flush: true);
|
|
await temporary.rename(_file.path);
|
|
}
|
|
|
|
@override
|
|
Future<AppSnapshot> restoreBackup() async {
|
|
if (!await _backup.exists()) throw StateError('没有可恢复的备份');
|
|
final previous = await _read(_backup);
|
|
final temporary = File('${_file.path}.tmp');
|
|
await temporary.writeAsString(jsonEncode(previous.toJson()), flush: true);
|
|
await temporary.rename(_file.path);
|
|
return previous;
|
|
}
|
|
}
|