flutter_archive 6.0.0 copy "flutter_archive: ^6.0.0" to clipboard
flutter_archive: ^6.0.0 copied to clipboard

Create and extract ZIP archive files in Android, iOS and macOS. Zip all files in a directory recursively or a given list of files.

example/lib/main.dart

import 'dart:io';

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:flutter_archive/flutter_archive.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin test app'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: _test,
            child: const Text("Test"),
          ),
        ),
      ),
    );
  }

  final _appDataDir = Directory.systemTemp;

  static const _dataFilesBaseDirectoryName = "store";
  final _dataFiles = {
    "file1.txt": "abc",
    "file2.txt": "åäö",
    "subdir1/file3.txt": r"@_£$",
    "subdir1/subdir11/file4.txt": "123",
  };

  Future _test() async {
    print("Start test");
    // test createFromDirectory
    // case 1
    var zipFile = await _testZip(includeBaseDirectory: false, progress: true);
    await _testUnzip(zipFile, zipIncludesBaseDirectory: false);
    await _testUnzip(zipFile, progress: true);
    // case 2
    zipFile = await _testZip(includeBaseDirectory: true, progress: false);
    await _testUnzip(zipFile, zipIncludesBaseDirectory: true);

    // test createFromFiles
    // case 1
    zipFile = await _testZipFiles(includeBaseDirectory: false);
    await _testUnzip(zipFile, zipIncludesBaseDirectory: false);
    // case 2
    zipFile = await _testZipFiles(includeBaseDirectory: true);
    await _testUnzip(zipFile, zipIncludesBaseDirectory: true);

    print("DONE!");
  }

  Future<File> _testZip(
      {required bool includeBaseDirectory, bool progress = false}) async {
    print("_appDataDir=${_appDataDir.path}");
    final storeDir =
        Directory("${_appDataDir.path}${"/$_dataFilesBaseDirectoryName"}");

    _createTestFiles(storeDir);

    final zipFile = _createZipFile("testZip.zip");
    print("Writing to zip file: ${zipFile.path}");

    int onProgressCallCount1 = 0;

    try {
      await ZipFile.createFromDirectory(
        sourceDir: storeDir,
        zipFile: zipFile,
        recurseSubDirs: true,
        includeBaseDirectory: includeBaseDirectory,
        onZipping: progress
            ? (fileName, isDirectory, progress) {
                ++onProgressCallCount1;
                print('Zip #1:');
                print('progress: ${progress.toStringAsFixed(1)}%');
                print('name: $fileName');
                print('isDirectory: $isDirectory');
                return ZipFileOperation.includeItem;
              }
            : null,
      );
      assert(!progress || onProgressCallCount1 > 0);
    } on PlatformException catch (e) {
      print(e);
    }
    return zipFile;
  }

  Future<File> _testZipFiles({required bool includeBaseDirectory}) async {
    print("_appDataDir=${_appDataDir.path}");
    final storeDir =
        Directory("${_appDataDir.path}${"/$_dataFilesBaseDirectoryName"}");

    final testFiles = _createTestFiles(storeDir);

    final zipFile = _createZipFile("testZipFiles.zip");
    print("Writing files to zip file: ${zipFile.path}");

    try {
      await ZipFile.createFromFiles(
          sourceDir: storeDir,
          files: testFiles,
          zipFile: zipFile,
          includeBaseDirectory: includeBaseDirectory);
    } on PlatformException catch (e) {
      print(e);
    }
    return zipFile;
  }

  Future _testUnzip(File zipFile,
      {bool progress = false, bool zipIncludesBaseDirectory = false}) async {
    print("_appDataDir=${_appDataDir.path}");

    final destinationDir = Directory("${_appDataDir.path}/unzip");
    final destinationDir2 = Directory("${_appDataDir.path}/unzip2");

    if (destinationDir.existsSync()) {
      print("Deleting existing unzip directory: ${destinationDir.path}");
      destinationDir.deleteSync(recursive: true);
    }
    if (destinationDir2.existsSync()) {
      print("Deleting existing unzip directory: ${destinationDir2.path}");
      destinationDir2.deleteSync(recursive: true);
    }

    print("Extracting zip to directory: ${destinationDir.path}");
    destinationDir.createSync();
    // test concurrent extraction
    final extractFutures = <Future>[];
    int onExtractingCallCount1 = 0;
    int onExtractingCallCount2 = 0;
    try {
      extractFutures.add(ZipFile.extractToDirectory(
          zipFile: zipFile,
          destinationDir: destinationDir,
          onExtracting: progress
              ? (zipEntry, progress) {
                  ++onExtractingCallCount1;
                  print('Extract #1:');
                  print('progress: ${progress.toStringAsFixed(1)}%');
                  print('name: ${zipEntry.name}');
                  print('isDirectory: ${zipEntry.isDirectory}');
                  print(
                      'modificationDate: ${zipEntry.modificationDate!.toLocal().toIso8601String()}');
                  print('uncompressedSize: ${zipEntry.uncompressedSize}');
                  print('compressedSize: ${zipEntry.compressedSize}');
                  print('compressionMethod: ${zipEntry.compressionMethod}');
                  print('crc: ${zipEntry.crc}');
                  return ZipFileOperation.includeItem;
                }
              : null));

      extractFutures.add(ZipFile.extractToDirectory(
          zipFile: zipFile,
          destinationDir: destinationDir2,
          onExtracting: progress
              ? (zipEntry, progress) {
                  ++onExtractingCallCount2;
                  print('Extract #2:');
                  print('progress: ${progress.toStringAsFixed(1)}%');
                  print('name: ${zipEntry.name}');
                  print('isDirectory: ${zipEntry.isDirectory}');
                  print(
                      'modificationDate: ${zipEntry.modificationDate!.toLocal().toIso8601String()}');
                  print('uncompressedSize: ${zipEntry.uncompressedSize}');
                  print('compressedSize: ${zipEntry.compressedSize}');
                  print('compressionMethod: ${zipEntry.compressionMethod}');
                  print('crc: ${zipEntry.crc}');
                  return ZipFileOperation.includeItem;
                }
              : null));

      await Future.wait<void>(extractFutures);
      assert(onExtractingCallCount1 == onExtractingCallCount2);
      assert(!progress || onExtractingCallCount1 > 0);
    } on PlatformException catch (e) {
      print(e);
    }

    // verify unzipped files
    if (zipIncludesBaseDirectory) {
      _verifyFiles(
          Directory("${destinationDir.path}/$_dataFilesBaseDirectoryName"));
      _verifyFiles(
          Directory("${destinationDir2.path}/$_dataFilesBaseDirectoryName"));
    } else {
      _verifyFiles(destinationDir);
      _verifyFiles(destinationDir2);
    }
  }

  File _createZipFile(String fileName) {
    final zipFilePath = "${_appDataDir.path}/$fileName";
    final zipFile = File(zipFilePath);

    if (zipFile.existsSync()) {
      print("Deleting existing zip file: ${zipFile.path}");
      zipFile.deleteSync();
    }
    return zipFile;
  }

  List<File> _createTestFiles(Directory storeDir) {
    if (storeDir.existsSync()) {
      storeDir.deleteSync(recursive: true);
    }
    storeDir.createSync();
    final files = <File>[];
    for (final fileName in _dataFiles.keys) {
      final file = File("${storeDir.path}/$fileName");
      file.createSync(recursive: true);
      print("Writing file: ${file.path}");
      file.writeAsStringSync(_dataFiles[fileName]!);
      files.add(file);
    }

    // verify created files
    _verifyFiles(storeDir);

    return files;
  }

  void _verifyFiles(Directory filesDir) {
    print("Verifying files at: ${filesDir.path}");
    final extractedItems = filesDir.listSync(recursive: true);
    for (final item in extractedItems) {
      print("extractedItem: ${item.path}");
    }
    print("File count: ${extractedItems.length}");
    assert(extractedItems.whereType<File>().length == _dataFiles.length,
        "Invalid number of files");
    for (final fileName in _dataFiles.keys) {
      final file = File('${filesDir.path}/$fileName');
      print("Verifying file: ${file.path}");
      assert(file.existsSync(), "File not found: ${file.path}");
      final content = file.readAsStringSync();
      assert(content == _dataFiles[fileName],
          "Invalid file content: ${file.path}");
    }
    print("All files ok");
  }
}
155
likes
0
pub points
98%
popularity

Publisher

verified publisherkineapps.com

Create and extract ZIP archive files in Android, iOS and macOS. Zip all files in a directory recursively or a given list of files.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter

More

Packages that depend on flutter_archive