file_size_calculator_util.dart 2.1 KB

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