compress and extract files in async mode
Opened this issue · 3 comments
``when trying to compress and extract files, my ui freezes even though i am using async functions. so may i ask if there is a solution or a simple working example?
below is my functions for compression and extraction.
Future<void> compressFiles(
List<PlatformFile> inFiles, String outFilePath, Function callback) async {
if (inFiles.isEmpty || outFilePath.isEmpty) return;
var encoder = ZipFileEncoder();
encoder.create(outFilePath);
int count = 0;
for (int i = 0; i < inFiles.length; i++) {
PlatformFile file = inFiles[i];
await callback(count / inFiles.length);
if (file.path == null) continue;
if (await Directory(file.path!).exists()) {
await encoder.addDirectory(Directory(file.path!));
} else {
await encoder.addFile(File(file.path!));
}
count++;
}
await callback(1.0);
encoder.close();
return;
}
bool extractFiles(String inFilePath, String outFilePath, Function callback) {
if (inFilePath.isEmpty || outFilePath.isEmpty) return false;
final bytes = File(inFilePath).readAsBytesSync();
final archive = ZipDecoder().decodeBytes(bytes);
extractArchiveToDisk(archive, outFilePath, asyncWrite: true);
int fileCount = archive.files.length;
int count = 0;
for (final file in archive) {
callback(count / fileCount);
final filename = file.name;
if (file.isFile) {
final data = file.content as List<int>;
File("$outFilePath\\$filename")
..createSync(recursive: true)
..writeAsBytesSync(data);
} else {
Directory("$outFilePath\\$filename").create(recursive: true);
}
count++;
}
callback(1.0);
return true;
}
}
Spawning an isolate using compute() will help not freeze the UI completely but like you, the problem I've found is that the archive process itself is so multi-threaded under the hood that it maxes out all 8 cores on my computer (windows 11).
Threads count utilization needs to be accessible to the outside world. Archiving large files is useless in its current form as it blocks the entire operating system.
A package like cpu_reader could be used detect CPU core number. Then the archive process could be spawned on an isolate utilizing (say) only 6 of the 8 cores thus leaving the system responsive.
The archive library does not use multithreading, because Dart doesn't prove multithreading beyond isolates.
you can try the extractFileToDisk method with asyncWrite=true