Flutter: Copy ZIP folder with all subfolders from assets to application documents directory

Tue, May 9, 2023

Read in 3 minutes

In this post we learn how to copy zip folder with all the files and subfolders from assets to application documents directory in Flutter

This function copies the zip folder with all its files and subfolders from assets to application documents folder. Here we are using archive package for our purpose. If you want the detailed explanation of this code scroll down see the breakdown of it.

Future<void> copyZipFolder(String zipFolderName) async {
    try {
      final bytes = await rootBundle.load('assets/$zipFolderName.zip');
      final dir = await Directory.systemTemp.createTemp(zipFolderName);
      final zipFile = File('${dir.path}/$zipFolderName.zip');
      await zipFile.writeAsBytes(bytes.buffer.asUint8List());
      final zipBytes = zipFile.readAsBytesSync();
      final archive = ZipDecoder().decodeBytes(zipBytes);
      final zipFolder = Directory('${dir.path}/$zipFolderName');
      await zipFolder.create(recursive: true);
      for (final f in archive) {
        final filename = '${dir.path}/${f.name}';
        if (f.isFile) {
          final data = f.content as List<int>;
          final file = File(filename);
          await file.create(recursive: true);
          await file.writeAsBytes(data);
        } else {
          final dir = Directory(filename);
          await dir.create(recursive: true);
        }
      }
      final documentsDir = await getApplicationDocumentsDirectory();
      final destinationFolder =
          Directory('${documentsDir.path}/$zipFolderName');
      if (await destinationFolder.exists()) {
        await destinationFolder.delete(recursive: true);
      }
      await zipFolder.rename(destinationFolder.path);
    } catch (e) {
      log('Error copying $zipFolderName.zip: $e');
    }
  }

Here’s a step-by-step breakdown of the code:

  1. The function starts by using rootBundle to load the contents of the zip folder from the app’s assets folder into memory as a byte array.
final bytes = await rootBundle.load('assets/$zipFolderName.zip');
  1. The code then creates a temporary directory using the Directory.systemTemp method and names it after the zipFolderName.
final dir = await Directory.systemTemp.createTemp(zipFolderName);
  1. The byte array is written to a file named $zipFolderName.zip in the temporary directory.
final zipFile = File('${dir.path}/$zipFolderName.zip');
await zipFile.writeAsBytes(bytes.buffer.asUint8List());
  1. The bytes of the zip file are then read and decoded using the ZipDecoder class from the archive package.
final zipBytes = zipFile.readAsBytesSync();
final archive = ZipDecoder().decodeBytes(zipBytes);
  1. A new directory is created in the temporary directory with the same name as the zipFolderName.
final zipFolder = Directory('${dir.path}/$zipFolderName');
await zipFolder.create(recursive: true);
  1. The contents of the decoded zip file are iterated through and each file is either written to the disk as a new file or a new directory is created.
for (final f in archive) {
  final filename = '${dir.path}/${f.name}';
  if (f.isFile) {
    final data = f.content as List<int>;
    final file = File(filename);
    await file.create(recursive: true);
    await file.writeAsBytes(data);
  } else {
    final dir = Directory(filename);
    await dir.create(recursive: true);
  }
}
  1. Finally, the contents of the temporary directory are renamed to the app’s documents directory, overwriting any existing files with the same name.
final documentsDir = await getApplicationDocumentsDirectory();
final destinationFolder = Directory('${documentsDir.path}/$zipFolderName');
if (await destinationFolder.exists()) {
  await destinationFolder.delete(recursive: true);
}
await zipFolder.rename(destinationFolder.path);

To use the archive package in your project, you’ll need to add it to your pubspec.yaml file as a dependency. Here’s an example of how to do this:

dependencies:
  archive: ^3.1.2

You can then import the package at the top of your Dart file with:

import 'package:archive/archive.dart';

Shohruh AK





See Also

How to create animated loading button in Flutter
How to publish Flutter app on Play Store: Beginner guide
How to Create Dotted Border Container in Flutter
FocusableActionDetector Flutter Widget: How to use it
How to Use 'sqflite_ffi' Database Package in Flutter