import 'dart:io'; import 'package:path/path.dart' as p; import 'package:path_provider/path_provider.dart'; /// 암호 보관함 [보기] 에서 잠깐 푼 파일을 두는 곳 (관리자 지시 10/21): 공유 폴더 (Download · 시스템 TEMP) 가 아니라 /// 앱 전용 - Android getCacheDir (다른 앱이 못 봄), Windows 앱 데이터 폴더의 temp. 시험에서 바꾼다 Future Function() vaultViewRootOf = () async { if (Platform.isAndroid) return getTemporaryDirectory(); return Directory(p.join((await getApplicationSupportDirectory()).path, 'temp')); }; /// 푼 파일을 두는 폴더 이름 앞 (실행마다 새 폴더) const vaultViewPrefix = 'jj_vault_view_'; /// 보관함 [꺼내기] 가 받는 폴더에 잠깐 쓰는 평문 "이름.jjvtmp" 기록 (관리자 지시 10/21): 쓰기 시작할 때 적고 끝나면 지운다. /// 앱이 강제로 꺼져 남은 것은 다음에 켤 때 [cleanVaultExportJournal] 이 지운다 (기록에 있는 것만 - 사용자 폴더를 뒤지지 않음) class VaultExportJournal { final String root; VaultExportJournal(this.root); static const name = 'jj_vault_exporting.txt'; File get _file => File(p.join(root, name)); List _read() { try { return _file.readAsLinesSync().where((x) => x.trim().isNotEmpty).toList(); } catch (_) { return []; } } void _write(List lines) { try { if (lines.isEmpty) { if (_file.existsSync()) _file.deleteSync(); } else { Directory(root).createSync(recursive: true); _file.writeAsStringSync('${lines.join('\n')}\n', flush: true); } } catch (_) {} } void add(String tmp) => _write([..._read().where((x) => x != tmp), tmp]); void remove(String tmp) => _write(_read().where((x) => x != tmp).toList()); } /// 앱을 켤 때: 꺼내기 기록에 남은 ".jjvtmp" 를 지우고 기록도 지운다. 지운 경로 List cleanVaultExportJournal(String root) { final j = VaultExportJournal(root); final removed = []; for (final x in j._read()) { if (!x.endsWith('.jjvtmp')) continue; // 기록이 깨졌어도 다른 파일은 지우지 않음 try { final f = File(x); if (f.existsSync()) { f.deleteSync(); removed.add(x); } } catch (_) {} } j._write([]); return removed; } /// 앱이 강제로 꺼져 남은 보기 폴더를 지운다 (앱을 켤 때 - 그때는 보관함이 열려 있지 않음). 지운 이름 List removeStaleVaultViews(String root) { final removed = []; try { for (final e in Directory(root).listSync(followLinks: false)) { final name = p.basename(e.path); if (e is! Directory || !name.startsWith(vaultViewPrefix)) continue; try { e.deleteSync(recursive: true); removed.add(name); } catch (_) {} } } catch (_) {} return removed; }