| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- import 'dart:ffi';
- import 'dart:io';
- import 'package:classify_photo/classify_photo.dart';
- import 'package:flutter/cupertino.dart';
- import 'package:wechat_assets_picker/wechat_assets_picker.dart';
- import 'package:photo_manager/photo_manager.dart';
- class FileSizeCalculatorUtil {
- static final Map<String, double> fileSizeCache = {};
- static Future<void> calculateTotalSizeByIOS({
- required Set<String> assetIds,
- required Function(double) updateValue,
- }) async {
- if (assetIds.isEmpty) {
- updateValue(0);
- return;
- }
- double totalSize = 0;
- totalSize =
- await ClassifyPhoto().calculatePhotosSize(assetIds.toList()) / 1024;
- updateValue(totalSize);
- }
- static Future<void> calculateTotalSizeByAndroid({
- required Set<String> assetIds,
- required Function(double) updateValue,
- }) async {
- if (assetIds.isEmpty) {
- updateValue(0);
- return;
- }
- double totalSize = 0;
- final uncasedIds =
- assetIds.where((id) => !fileSizeCache.containsKey(id)).toSet();
- // **1️⃣ 先处理缓存中的文件**
- totalSize = assetIds.fold(0, (prev, id) => prev + (fileSizeCache[id] ?? 0));
- updateValue(totalSize);
- // **2️⃣ 分批处理未缓存的文件**
- const batchSize = 20;
- for (int i = 0; i < uncasedIds.length; i += batchSize) {
- if (assetIds.isEmpty) {
- updateValue(0);
- return;
- }
- final batch = uncasedIds.skip(i).take(batchSize);
- final sizes =
- await Future.wait(batch.map(FileSizeCalculatorUtil.getFileSize));
- totalSize += sizes.fold(0, (sum, size) => sum + size);
- // **再检查一次是否被清空,避免无意义计算**
- if (assetIds.isEmpty) {
- updateValue(0);
- return;
- }
- await Future.delayed(Duration.zero);
- updateValue(totalSize);
- }
- updateValue(totalSize);
- }
- static Future<void> calculateTotalSize({
- required Set<String> assetIds,
- required Function(double) updateValue,
- }) async {
- if (Platform.isIOS) {
- await calculateTotalSizeByIOS(
- assetIds: assetIds, updateValue: updateValue);
- } else {
- await calculateTotalSizeByAndroid(
- assetIds: assetIds, updateValue: updateValue);
- }
- }
- /// 获取文件大小
- static Future<double> getFileSize(String assetId) async {
- if (fileSizeCache.containsKey(assetId)) {
- return fileSizeCache[assetId]!;
- }
- final entity = await AssetEntity.fromId(assetId);
- if (entity == null) return 0;
- if (Platform.isAndroid) {
- final String? path = entity.relativePath;
- if (path == null) return 0;
- final file = File("/storage/emulated/0/$path${entity.title}");
- // print("file path: ${await file.path}");
- if (!await file.exists()) {
- return 0;
- }
- // print("file size: ${await file.length()}");
- final double size = (await file.length()) / 1024;
- fileSizeCache[assetId] = size;
- return size;
- } else {
- final file = await entity.file;
- if (file == null) return 0;
- if (!await file.exists()) {
- return 0;
- }
- try {
- final double size = (await file.length()) / 1024;
- fileSizeCache[assetId] = size;
- try {
- await file.delete();
- } catch (e) {
- debugPrint("Delete file error: $e");
- }
- if (size <= 0) {
- return 0;
- }
- return size;
- } catch (e) {
- return 0;
- }
- }
- }
- }
|