session_store.dart 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. import 'dart:convert';
  2. import 'dart:io';
  3. import 'package:flutter/foundation.dart';
  4. import 'package:path_provider/path_provider.dart';
  5. /// 会话存档:Symja 定义 + 命令历史。
  6. ///
  7. /// 写入走「临时文件 + 改名」,保证原子性:写到一半被杀不会留下半个坏存档,
  8. /// 否则下次启动 JSON 解析失败就会丢掉全部变量。
  9. class SessionStore {
  10. static const _fileName = 'session.json';
  11. static const _version = 1;
  12. Future<File> _file() async {
  13. final dir = await getApplicationDocumentsDirectory();
  14. return File('${dir.path}/$_fileName');
  15. }
  16. /// 读存档。任何异常都当成「没有存档」返回 null —— 存档问题绝不能挡住启动。
  17. Future<Map<String, dynamic>?> load() async {
  18. try {
  19. final f = await _file();
  20. if (!f.existsSync()) return null;
  21. final decoded = jsonDecode(await f.readAsString());
  22. if (decoded is! Map<String, dynamic>) return null;
  23. if (decoded['version'] != _version) return null;
  24. return decoded;
  25. } catch (e) {
  26. debugPrint('读取存档失败,按空存档处理: $e');
  27. return null;
  28. }
  29. }
  30. Future<void> save(Map<String, dynamic> data) async {
  31. try {
  32. final f = await _file();
  33. final tmp = File('${f.path}.tmp');
  34. await tmp.writeAsString(
  35. jsonEncode(<String, dynamic>{'version': _version, ...data}),
  36. flush: true,
  37. );
  38. await tmp.rename(f.path);
  39. } catch (e) {
  40. debugPrint('写入存档失败: $e');
  41. }
  42. }
  43. }