archive icon indicating copy to clipboard operation
archive copied to clipboard

compress and extract files in async mode

Open moamen-gamal opened this issue 1 year ago • 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;
  }
}

moamen-gamal avatar Dec 25 '22 09:12 moamen-gamal

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.

sidetraxaudio avatar Jan 14 '23 05:01 sidetraxaudio

The archive library does not use multithreading, because Dart doesn't prove multithreading beyond isolates.

brendan-duncan avatar Feb 03 '23 03:02 brendan-duncan

you can try the extractFileToDisk method with asyncWrite=true

Hilbert2048 avatar Apr 09 '24 17:04 Hilbert2048