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:
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');
Directory.systemTemp
method and names it after the zipFolderName
.final dir = await Directory.systemTemp.createTemp(zipFolderName);
$zipFolderName.zip
in the temporary directory.final zipFile = File('${dir.path}/$zipFolderName.zip');
await zipFile.writeAsBytes(bytes.buffer.asUint8List());
ZipDecoder
class from the archive
package.final zipBytes = zipFile.readAsBytesSync();
final archive = ZipDecoder().decodeBytes(zipBytes);
zipFolderName
.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);
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';