file_size_calculator_util.dart 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import 'dart:ffi';
  2. import 'package:classify_photo/classify_photo.dart';
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:wechat_assets_picker/wechat_assets_picker.dart';
  5. import 'package:photo_manager/photo_manager.dart';
  6. class FileSizeCalculatorUtil {
  7. static final Map<String, double> fileSizeCache = {};
  8. static Future<void> calculateTotalSizeByIOS({
  9. required Set<String> assetIds,
  10. required Function(double) updateValue,
  11. }) async {
  12. if (assetIds.isEmpty) {
  13. updateValue(0);
  14. return;
  15. }
  16. double totalSize = 0;
  17. totalSize = await ClassifyPhoto().calculatePhotosSize(assetIds.toList()) / 1024;
  18. updateValue(totalSize);
  19. }
  20. static Future<void> calculateTotalSize({
  21. required Set<String> assetIds,
  22. required Function(double) updateValue,
  23. }) async {
  24. if (assetIds.isEmpty) {
  25. updateValue(0);
  26. return;
  27. }
  28. double totalSize = 0;
  29. final uncasedIds =
  30. assetIds.where((id) => !fileSizeCache.containsKey(id)).toSet();
  31. // **1️⃣ 先处理缓存中的文件**
  32. totalSize = assetIds.fold(0, (prev, id) => prev + (fileSizeCache[id] ?? 0));
  33. updateValue(totalSize);
  34. // **2️⃣ 分批处理未缓存的文件**
  35. const batchSize = 20;
  36. for (int i = 0; i < uncasedIds.length; i += batchSize) {
  37. if (assetIds.isEmpty) {
  38. updateValue(0);
  39. return;
  40. }
  41. final batch = uncasedIds.skip(i).take(batchSize);
  42. final sizes =
  43. await Future.wait(batch.map(FileSizeCalculatorUtil.getFileSize));
  44. totalSize += sizes.fold(0, (sum, size) => sum + size);
  45. // **再检查一次是否被清空,避免无意义计算**
  46. if (assetIds.isEmpty) {
  47. updateValue(0);
  48. return;
  49. }
  50. await Future.delayed(Duration.zero);
  51. updateValue(totalSize);
  52. }
  53. updateValue(totalSize);
  54. }
  55. /// 获取文件大小
  56. static Future<double> getFileSize(String assetId) async {
  57. if (fileSizeCache.containsKey(assetId)) {
  58. return fileSizeCache[assetId]!;
  59. }
  60. final entity = await AssetEntity.fromId(assetId);
  61. if (entity == null) return 0;
  62. final file = await entity.file;
  63. if (file == null) return 0;
  64. if (!await file.exists()) {
  65. return 0;
  66. }
  67. try {
  68. final double size = (await file.length()) / 1024;
  69. fileSizeCache[assetId] = size;
  70. try {
  71. await file.delete();
  72. } catch (e) {
  73. debugPrint("Delete file error: $e");
  74. }
  75. if (size <= 0) {
  76. return 0;
  77. }
  78. return size;
  79. } catch (e) {
  80. return 0;
  81. }
  82. }
  83. }