Flutter plugin for creating and extracting ZIP files.

Related tags

Map flutter-plugin
Overview

flutter_archive

Create and extract ZIP archive files. Uses Android/iOS/macOS platform APIs for high performance and optimal memory usage.

Features

  • Supports Android (API level 16+), iOS 9+ and macOS 10.11+.
  • Modern plugin implementation based on Kotlin (Android) and Swift (iOS/macOS).
  • Uses background processing to keep UI responsive.
  • Zip all files in a directory (optionally recursively).
  • Zip a given list of files.
  • Unzip an archive file to a given directory.
  • Progress reporting.
  • Extract and zip files selectively (allows excluding files).

Examples

Create a zip file from a directory

  final dataDir = Directory("data_dir_path");
  try {
    final zipFile = File("zip_file_path");
    ZipFile.createFromDirectory(
        sourceDir: dataDir, zipFile: zipFile, recurseSubDirs: true);
  } catch (e) {
    print(e);
  }

Create a zip file from a given list of files.

  final sourceDir = Directory("source_dir");
  final files = [
    File(sourceDir.path + "file1"),
    File(sourceDir.path + "file2")
  ];
  final zipFile = File("zip_file_path");
  try {
    ZipFile.createFromFiles(
        sourceDir: sourceDir, files: files, zipFile: zipFile);
  } catch (e) {
    print(e);
  }

Extract a ZIP archive

  final zipFile = File("zip_file_path");
  final destinationDir = Directory("destination_dir_path");
  try {
    ZipFile.extractToDirectory(zipFile: zipFile, destinationDir: destinationDir);
  } catch (e) {
    print(e);
  }

Get progress info while extracting a zip archive.

  final zipFile = File("zip_file_path");
  final destinationDir = Directory("destination_dir_path");
  try {
    await ZipFile.extractToDirectory(
        zipFile: zipFile,
        destinationDir: destinationDir,
        onExtracting: (zipEntry, progress) {
          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;
        });
  } catch (e) {
    print(e);
  }
Comments
  • Performance issues on very old iOS devices

    Performance issues on very old iOS devices

    Hello,

    I'm developing a flutter application which is doing some unzip operations. It's nothing special, basically just unzipping files and placing them on the desired location. The files that I'm unzipping are typically between 50-150MB (zipped) and 150-450MB (unzipped).

    At first, I was implementing the unzipping logic in plain flutter using the archive package. During testing, I recognized that the library isn't able to extract larger zip files on low memory devices. It starts unzipping but doesn't check its memory consumption until the system decides to kill the application because it's using too much RAM.

    This is where your package comes into play. I was looking around and found it quite new on pub.dev - so I gave it a try.

    Once I replaced the components and started testing with your package, I was amazed that on Android everything runs smoothly and without any noticeable UI/input lags.

    Then I started testing on iOS and recognized a few things.

    Before going into details, here are some benchmarks I took:

    Test Scenario & Benchmark

    Target File: 145MB ZIP file (450MB once extracted)

    The goal is to extract the archive using flutter_archive

    iPad Air 2013

    On the old iPad Air 2013, the unzip operation for the ZIP file took about 20mins. During this time the CPU was constantly at 100%. Avg. read speed: 1MB Chunks every 3-5 seconds Avg. write speed: 0.3MB/s

    -> This results in very low memory consumption (which is very nice) but takes a way too long to unzip the archive.

    iPad Air 3 (2019)

    On the newer iPad Air 3, the unzip operation for the ZIP file took about 5mins. During this time the CPU was as well at 100% (constantly). Avg. read speed: ~ 4MB Chunks every 3-5 seconds Avg. write speed: ~ 2MB/s

    -> Same results as with the iPad Air 2013 (regarding memory). But still took a way too long to unzip.

    Issue

    Once I evaluated the problems I mentioned above I started looking into the source code of your package. The Android implementation looks good to me. For the iOS implementation, it seems like you're using ZipFoundation.

    Is there a way to somehow configure the read/write chunk size of the archives? AFAIK the library allows you to configure the chunk size which it uses to read/write data.

    Could you by any chance check if it's possible to adjust the chunk size and add additional parameters to your implementation to be able to customize these things?

    This would be really appreciated. If you need further information from my side, please let me know.

    Regards!

    opened by PDDStudio 10
  • Progress of unpacking

    Progress of unpacking

    After switching from archive I was happy about background processing. But it would be cool to see the unpacking process from the past plugin like this:

       for (final file in archive) {
          progress = ((count / archive.files.length) * 100).toInt();
          print('Install:  $progress');
          count++;
          final filename = file.name;
          if (file.isFile) {
            print('$filename');
            final data = file.content as List<int>;
            File('${dir.path}/' + filename)
              ..createSync(recursive: true)
              ..writeAsBytesSync(data);
          } else {
            Directory('${dir.path}/' + filename)..create(recursive: true);
          }
        }
    
    opened by the-thirteenth-fox 9
  • mac version not working due to regular file instead of symlink

    mac version not working due to regular file instead of symlink

    First of all, thanks for providing this library 👍

    I'm trying to build a Mac desktop app and when Flutter runs pub get, I see the following: (stripping prefix dir /opt/flutter/.pub-cache/hosted/pub.dartlang.org/)

    $ ls -l flutter_archive-2.0.1/macos/Classes/SwiftFlutterArchivePlugin.swift
    -rwxr-xr-x  1 willem  wheel    49B Dec 15 13:03 /flutter_archive-2.0.1/macos/Classes/SwiftFlutterArchivePlugin.swift
    $ cat /flutter_archive-2.0.1/macos/Classes/SwiftFlutterArchivePlugin.swift
    ../../ios/Classes/SwiftFlutterArchivePlugin.swift
    

    and this triggers a Swift error Expressions are not allowed at the top level since it's a regular file instead of a symlink.

    When I remove the file and actually create a symlink towards that path, it works:

    $ rm /flutter_archive-2.0.1/macos/Classes/SwiftFlutterArchivePlugin.swift
    $ ln -s ../../ios/Classes/SwiftFlutterArchivePlugin.swift /flutter_archive-2.0.1/macos/Classes/SwiftFlutterArchivePlugin.swift
    $ ls -l /flutter_archive-2.0.1/macos/Classes/SwiftFlutterArchivePlugin.swift
    lrwxr-xr-x  1 willem  wheel  49 Jan 28 21:06 /flutter_archive-2.0.1/macos/Classes/SwiftFlutterArchivePlugin.swift -> ../../ios/Classes/SwiftFlutterArchivePlugin.swift
    

    now my app starts running.


    I tried to create a PR by making the file a symlink, but I saw it already is a symlink.

    So maybe pub doesn't work too well with symlinks, either during publishing or during downloading 🤷‍♂️ I did find this issue, which might be related.

    NB: my flutter --version is:

    Flutter 1.26.0-12.0.pre • channel dev • https://github.com/flutter/flutter.git
    Framework • revision a706cd2112 (2 weeks ago) • 2021-01-14 18:20:26 -0500
    Engine • revision effb529ece
    Tools • Dart 2.12.0 (build 2.12.0-224.0.dev)
    
    opened by fibbers 6
  • Why does it have a sourceDir argument in ZipFile.createFromFiles?

    Why does it have a sourceDir argument in ZipFile.createFromFiles?

    Shouldn't List files would be enough? So I selected some files from different places, So they aren't in a single directory, So should I keep the sourceDir to be the root Directory of the entire phone? I think the best would be to copy all the files to some tempDir and pass it? But still what has it anything to do? List files goes in --> A Zip File should come out, I mean yeah write to a zip file, but why take a sourceDir?

    opened by ash-hashtag 5
  • No implementation found for method zipDirectory on channel flutter_archive

    No implementation found for method zipDirectory on channel flutter_archive

    Hi

    I'm getting this error trying to use flutter-archive:

    [VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: MissingPluginException(No implementation found for method zipDirectory on channel flutter_archive)

    I've tried flutter packages get flutter packages upgrade Run pod install in iOS folder

    In my podfile I have: platform :ios, '13.0'

    in XCode 11.5 I set the deployment target to iOS 13

    Anything I can try or is there any further debug info you need?

    Cheers

    opened by lucasjbyoung 5
  • I have gotten this error when try to excuse pod install

    I have gotten this error when try to excuse pod install

    I have gotten this error when try to excuse pod install

    [!] CocoaPods could not find compatible versions for pod "flutter_archive": In Podfile: flutter_archive (from .symlinks/plugins/flutter_archive/ios)

    Specs satisfying the flutter_archive (from.symlinks/plugins/flutter_archive/ios) dependency were found, but they required a higher minimum deployment target.

    opened by islam-Ellithy 5
  • deps: update dependency ZIPFoundation to 0.9.13

    deps: update dependency ZIPFoundation to 0.9.13

    Update the ZIPFoundation dependency to version 0.9.13. The deployment target was bumped to 12.0. The reason behind that update is to fix some unzipping issues on iOS with .msa files.

    opened by daniel-possienke 4
  • Unable to unzip file due to error - open failed: EPERM (Operation not permitted)

    Unable to unzip file due to error - open failed: EPERM (Operation not permitted)

    Getting the following error when trying to extract a zip file at this path /storage/emulated/0/Test:

    D/FilePickerDelegate(12452): [SingleFilePick] File URI:content://com.android.externalstorage.documents/tree/primary%3ATest/document/primary%3ATest
    I/flutter (12452): result: /storage/emulated/0/Test
    D/FlutterArchivePlugin(11785): onMethodCall / unzip...
    D/FlutterArchivePlugin(11785): destinationDir.path: /storage/emulated/0/Test
    D/FlutterArchivePlugin(11785): destinationDir.canonicalPath: /storage/emulated/0/Test
    D/FlutterArchivePlugin(11785): destinationDir.absolutePath: /storage/emulated/0/Test
    D/FlutterArchivePlugin(11785): zipEntry fileName=c4611_sample_explain 0.pdf, compressedSize=150723, size=177590, crc=1899967778
    D/FlutterArchivePlugin(11785): Writing entry to file: /storage/emulated/0/Test/c4611_sample_explain 0.pdf
    W/System.err(11785): java.io.FileNotFoundException: /storage/emulated/0/Test/c4611_sample_explain 0.pdf: open failed: EPERM (Operation not permitted)
    W/System.err(11785): 	at libcore.io.IoBridge.open(IoBridge.java:492)
    W/System.err(11785): 	at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
    W/System.err(11785): 	at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
    W/System.err(11785): 	at com.kineapps.flutterarchive.FlutterArchivePlugin.unzip(FlutterArchivePlugin.kt:359)
    W/System.err(11785): 	at com.kineapps.flutterarchive.FlutterArchivePlugin$onMethodCall$3$1.invokeSuspend(FlutterArchivePlugin.kt:148)
    W/System.err(11785): 	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    W/System.err(11785): 	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
    W/System.err(11785): 	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:561)
    W/System.err(11785): 	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:727)
    W/System.err(11785): 	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:667)
    W/System.err(11785): 	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:655)
    W/System.err(11785): Caused by: android.system.ErrnoException: open failed: EPERM (Operation not permitted)
    W/System.err(11785): 	at libcore.io.Linux.open(Native Method)
    W/System.err(11785): 	at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
    W/System.err(11785): 	at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
    W/System.err(11785): 	at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
    W/System.err(11785): 	at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7542)
    W/System.err(11785): 	at libcore.io.IoBridge.open(IoBridge.java:478)
    W/System.err(11785): 	... 10 more
    E/flutter (11785): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: PlatformException(unzip_error, /storage/emulated/0/Test/c4611_sample_explain 0.pdf: open failed: EPERM (Operation not permitted), java.io.FileNotFoundException: /storage/emulated/0/Test/c4611_sample_explain 0.pdf: open failed: EPERM (Operation not permitted), null)
    E/flutter (11785): #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:597:7)
    E/flutter (11785): #1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:158:18)
    E/flutter (11785): <asynchronous suspension>
    E/flutter (11785): #2      ZipFile.extractToDirectory (package:flutter_archive/flutter_archive.dart:141:7)
    E/flutter (11785): <asynchronous suspension>
    E/flutter (11785): 
    

    But on this path /storage/emulated/0/Download/Test , it works fine :

    D/FilePickerDelegate(12452): [SingleFilePick] File URI:content://com.android.externalstorage.documents/tree/primary%3ADownload%2FTest/document/primary%3ADownload%2FTest
    I/flutter (12452): result: /storage/emulated/0/Download/Test
    D/FlutterArchivePlugin(12452): onMethodCall / unzip...
    D/FlutterArchivePlugin(12452): destinationDir.path: /storage/emulated/0/Download/Test
    D/FlutterArchivePlugin(12452): destinationDir.canonicalPath: /storage/emulated/0/Download/Test
    D/FlutterArchivePlugin(12452): destinationDir.absolutePath: /storage/emulated/0/Download/Test
    D/FlutterArchivePlugin(12452): zipEntry fileName=c4611_sample_explain 0.pdf, compressedSize=150723, size=177590, crc=2506166364
    D/FlutterArchivePlugin(12452): Writing entry to file: /storage/emulated/0/Download/Test/c4611_sample_explain 0.pdf
    D/FlutterArchivePlugin(12452): zipEntry fileName=c4611_sample_explain 1.pdf, compressedSize=97717, size=106241, crc=3092968696
    D/FlutterArchivePlugin(12452): Writing entry to file: /storage/emulated/0/Download/Test/c4611_sample_explain 1.pdf
    D/FlutterArchivePlugin(12452): ...onMethodCall / unzip
    

    Do you have any idea why this is happening? Then please let me know.

    Thank you.

    opened by brightseagit 4
  • java.util.zip.ZipException: No entries

    java.util.zip.ZipException: No entries

    Getting Exception while creating zip in android using latest version and V0.1.4 Details Exception below W/System.err(24617): java.util.zip.ZipException: No entries W/System.err(24617): at java.util.zip.ZipOutputStream.finish(ZipOutputStream.java:363) W/System.err(24617): at java.util.zip.DeflaterOutputStream.close(DeflaterOutputStream.java:239) W/System.err(24617): at java.util.zip.ZipOutputStream.close(ZipOutputStream.java:383) W/System.err(24617): at kotlin.io.CloseableKt.closeFinally(Closeable.kt:53) W/System.err(24617): at com.kineapps.flutterarchive.FlutterArchivePlugin.zip(FlutterArchivePlugin.kt:155) W/System.err(24617): at com.kineapps.flutterarchive.FlutterArchivePlugin.access$zip(FlutterArchivePlugin.kt:32) W/System.err(24617): at com.kineapps.flutterarchive.FlutterArchivePlugin$onMethodCall$1$1.invokeSuspend(FlutterArchivePlugin.kt:101) W/System.err(24617): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) W/System.err(24617): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56) W/System.err(24617): at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:561) W/System.err(24617): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:727) W/System.err(24617): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:667) W/System.err(24617): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:655)

    opened by gawkarhari 4
  • Seeing build issues on Android after upgrading to 2.12.0-4.1.pre on flutter beta channel

    Seeing build issues on Android after upgrading to 2.12.0-4.1.pre on flutter beta channel

    Below is the error message:

    ....../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_archive-4.2.0/android/src/main/kotlin/com/kineapps/flutterarchive/FlutterArchivePlugin.kt: (455, 58): 
    Object is not abstract and does not implement abstract member public abstract fun error(p0: String, p1: String?, p2: Any?): 
    Unit defined in io.flutter.plugin.common.MethodChannel.Result
    

    I don't see this issue on ios.

    This issue is preventing me to build on Android.

    is there a fix/workaround for the issue?

    opened by 91jaeminjo 3
  • Error while building for macos: expressions are not allowed at the top level

    Error while building for macos: expressions are not allowed at the top level

    [...]/.pub-cache/hosted/pub.dartlang.org/flutter_archive-4.1.0/macos/Classes/SwiftFlutterArchivePlugin.swift:1:1: error: expressions are not allowed at the top level
    ../../ios/Classes/SwiftFlutterArchivePlugin.swift
    ^
    

    I guess there is some problem with symlinks like described in #26

    Screenshot 2021-11-26 at 15 30 57 solves the issue
    opened by szediwy 3
  • Can I cover the target folder during decompression?

    Can I cover the target folder during decompression?

    PlatformException(UNZIP_ERROR, The file “xxx.data” couldn’t be saved in the folder “data” because a file with the same name already exists., null, null)

    opened by Allenxuxu 2
  • Return progress based on bytes , not on files

    Return progress based on bytes , not on files

    Hello KineApps. I want to first thank you for this plugin. Is it possible instead of giving the progress based on the number of files that are already archived to the number of bytes that are already archived? The problem is that there are cases where we have a lot of many files (some KB) and just a few big ones (more than 300MB). This affects the progress in a not very user-friendly manner. Thanks in advance.

    opened by savs90 0
  • propose

    propose

    Can it be compatible? This registration method. I hope it can be increased.

    public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registrar registrar) { final PackageInfoPlugin instance = new PackageInfoPlugin(); instance.onAttachedToEngine(registrar.context(), registrar.messenger()); }

    opened by git91895 0
flutter_map plugin to request and display the users location and heading on the map

The plugin is discontinued. Feel free to fork it or checkout similar plugins. Flutter Map – Location plugin A flutter_map plugin to request and displa

Fabian Rosenthal 19 Oct 11, 2022
Flutter plugin for forward and reverse geocoding

geocoder Forward and reverse geocoding. Usage Import package:geocoder/geocoder.dart, and use the Geocoder.local to access geocoding services provided

Aloïs Deniel 177 Dec 31, 2022
Flutter geolocation plugin for Android and iOS.

geolocation Flutter geolocation plugin for Android API 16+ and iOS 9+. Features: Manual and automatic location permission management Current one-shot

Loup 222 Jan 2, 2023
Android and iOS Geolocation plugin for Flutter

Flutter geolocator plugin The Flutter geolocator plugin is build following the federated plugin architecture. A detailed explanation of the federated

Baseflow 1k Jan 5, 2023
Android and iOS Geolocation plugin for Flutter

Flutter geolocator plugin The Flutter geolocator plugin is build following the federated plugin architecture. A detailed explanation of the federated

Baseflow 891 Nov 14, 2021
A Flutter plugin to easily handle realtime location in iOS and Android. Provides settings for optimizing performance or battery.

Flutter Location Plugin This plugin for Flutter handles getting a location on Android and iOS. It also provides callbacks when the location is changed

Guillaume Bernos 953 Dec 22, 2022
Android and iOS Geolocation plugin for Flutter

Flutter geolocator plugin The Flutter geolocator plugin is build following the federated plugin architecture. A detailed explanation of the federated

Baseflow 1k Dec 27, 2022
A Flutter plugin for integrating Google Maps in iOS, Android and Web applications

flutter_google_maps A Flutter plugin for integrating Google Maps in iOS, Android and Web applications. It is a wrapper of google_maps_flutter for Mobi

MarchDev Toolkit 86 Sep 26, 2022
A new flutter plugin for mapbox. You can use it for your map backgrounds inside flutter applications

A new flutter plugin for mapbox. You can use it for your map backgrounds inside flutter applications

Boris Gautier 5 Sep 14, 2022
A flutter plugin for Google Maps

IMPORTANT: This plugin is no longer under development Why? We initially built this plugin to fill an early gap in flutter. Since then, Google has made

AppTree Software, Inc 415 Dec 29, 2022
Flutter plugin to display a simple flat world map with animated points in real time

Flutter Simple Map Flutter plugin to display a simple flat world map with animated points in real time. Can be used as a presentation of online users,

Vladyslav Korniienko 7 Dec 8, 2022
Apple Maps Plugin for Flutter

apple_maps_flutter A Flutter plugin that provides an Apple Maps widget. The plugin relies on Flutter's mechanism for embedding Android and iOS views.

Luis Thein 50 Dec 31, 2022
Flutter plugin for launching maps

Map Launcher Map Launcher is a flutter plugin to find available maps installed on a device and launch them with a marker or show directions. Marker Na

Alex Miller 189 Dec 20, 2022
A Flutter plugin for appodeal

flutter_appodeal A Flutter plugin for iOS and Android to use Appodeal SDK in your apps Getting Started For help getting started with Flutter, view our

null 14 Feb 19, 2022
A flutter plugin that's decodes encoded google poly line string into list of geo-coordinates suitable for showing route/polyline on maps

flutter_polyline_points A flutter plugin that decodes encoded google polyline string into list of geo-coordinates suitable for showing route/polyline

Adeyemo Adedamola 75 Oct 25, 2022
OpenStreetMap plugin for flutter

flutter_osm_plugin Platform Support Android iOS Web supported ✔️ supported ✔️ (min iOS supported : 12) under-development osm plugin for flutter apps c

hamza mohamed ali 125 Dec 30, 2022
A Flutter plugin which provides 'Picking Place' using Google Maps widget

Google Maps Places Picker Refractored This is a forked version of google_maps_place_picker package, with added custom styling and features.

Varun 5 Nov 13, 2022
A plugin that offers widgets for Wear OS by Google

Flutter Wear Plugin A plugin that offers Flutter support for Wear OS by Google (Android Wear). To use this plugin you must set your minSdkVersion to 2

Flutter Community 114 Dec 18, 2022
Plugin for 'flutter_map' providing advanced caching functionality, with ability to download map regions for offline use. Also includes useful prebuilt widgets.

flutter_map_tile_caching A plugin for the flutter_map library to provide an easy way to cache tiles and download map regions for offline use. Installa

Luka S 69 Jan 3, 2023