Flutter文件压缩插件es_compression的使用

发布于 1周前 作者 zlyuanteng 来自 Flutter

Flutter文件压缩插件es_compression的使用

描述

ES Compression 是一个用于Dart的压缩框架,它提供了Brotli、Lz4、Zstd (Zstandard) 的FFI实现,并附带了预构建的二进制文件,支持Windows、Linux和Mac操作系统。该框架的设计灵感来源于VAST Platform中的Unified Compression Framework

更多关于此包的设计和实现细节,请参阅设计文档

以下是一个简单的编码/解码示例:

import 'dart:convert';
import 'package:es_compression/brotli.dart';
import 'package:es_compression/lz4.dart';
import 'package:es_compression/zstd.dart';

/// Brotli, Lz4, Zstd 使用示例
void main() {
  final bytes = utf8.encode('Hello Dart');
  for (final codec in [brotli, lz4, zstd]) {
    final encoded = codec.encode(bytes);
    final decoded = codec.decode(encoded);
    print(utf8.decode(decoded));
  }
}

可执行文件

bin子目录中,提供了以下可执行文件。

可执行文件 源代码 描述
escompress es_compress.dart 使用brotli、gzip、lz4和zstd对文件进行编码/解码

如果您想在命令行上使用escompress,可以使用pub global activate安装它:

> pub global activate es_compression

使用escompress命令

escompress是一个程序,将使用brotligziplz4zstd对文件进行编码/解码。

用户从命令行提供输入和输出文件名,默认情况下,通过输入或输出文件名的扩展名来确定使用哪种算法和编码/解码模式。用户也可以提供额外的命令行参数来明确这些决策。下面是一些例子。

示例

  • input.txt编码为output.lz4使用Lz4压缩:

    > escompress -i"input.txt" -o"output.lz4"
    
  • input.txt编码为output.lz4使用Lz4压缩,压缩级别为3:

    > escompress -l 3 -i"input.txt" -o"output.lz4"
    
  • input.brotli解码为output.txt使用Brotli压缩:

    > escompress -i"input.brotli" -o"output.txt"
    
  • input.txt编码为output.compressed使用Zstd压缩:

    > escompress -e -a zstd -i"input.txt" -o"output.compressed"
    
  • input.compressed解码为output.txt使用GZip压缩:

    > escompress -d -a gzip -i"input.compressed" -o"output.txt"
    
  • 打印帮助信息:

    > escompress -h
    

示例

example子目录中,提供了以下示例以演示转换器和框架的用法。

示例 描述
brotli_example.dart 使用基于FFI的Brotli实现进行一次性和流式编码/解码
lz4_example.dart 使用基于FFI的Lz4实现进行一次性和流式编码/解码
rle_example.dart 一个简单的RLE压缩示例,展示如何构建自定义编解码器
zstd_example.dart 使用基于FFI的Zstd实现进行一次性和流式编码/解码

运行(以brotli为例):

> dart example/brotli_example.dart

测试

test子目录中,提供了以下测试用例以测试压缩框架和编解码器实现。

测试 描述
benchmarks_test.dart 测试benchmark子目录中定义的基准测试
brotli_test.dart 测试基于FFI的Brotli实现的编码/解码
buffer_test.dart 测试压缩框架中的CodecBuffer及其相关类
escompress_test.dart 测试bin子目录中的escompress二进制文件
examples_test.dart 测试example子目录中定义的示例
lz4_test.dart 测试基于FFI的Lz4实现的编码/解码
zstd_test.dart 测试基于FFI的Zstd实现的编码/解码

运行测试套件:

> pub run test

基准测试

benchmark子目录中,提供了以下基准测试以帮助理解编解码器性能及参数选择(如缓冲区大小)带来的权衡。

基准测试 描述
brotli_benchmark.dart 测试基于FFI的Brotli实现的编码/解码基准测试
gzip_benchmark.dart 测试Dart SDK中的GZip实现的编码/解码基准测试
lz4_benchmark.dart 测试基于FFI的Lz4实现的编码/解码基准测试
zstd_benchmark.dart 测试基于FFI的Zstd实现的编码/解码基准测试

运行(以lz4为例):

> dart benchmark/lz4_benchmark.dart

部署

基于FFI的实现需要访问低级共享库(即.dll、.so、.dylib)。本包提供了一个灵活的库加载器,可以根据最终用户的部署需求进行定制。

默认情况下,解析顺序如下:

  1. 环境变量
  2. 包相对路径
  3. 脚本相对路径
  4. 操作系统依赖路径

用户提供的解析:用户可以通过提供用户指定的库路径覆盖上述解析。不同的策略用于定位共享库如下所述。

环境变量解析

环境变量可以被定义为提供指向共享库的路径。这要么是共享库文件的路径,要么是应该包含形如es{algo}_{os}{bitness}.{ext}的文件名的目录。例如,64位Windows上的lz4文件名为eslz4_win64.dll

编解码器 环境变量
brotli BROTLI_LIBRARY_PATH
lz4 LZ4_LIBRARY_PATH
zstd ZSTD_LIBRARY_PATH

包相对路径解析

预构建的共享库位于每个FFI编解码器实现的blob目录中。这些是由包维护者使用blob_builder工具构建的。

对于名为xxx的编解码器,默认情况下,分发的共享库预计位于lib/src/xxx/blobs

脚本相对路径解析

尝试在运行脚本的同一目录中找到共享库。共享库的名称应为形如es{algo}_{os}{bitness}.{ext}。例如,64位Linux上的zstd文件名为eszstd_linux64.so

操作系统依赖路径解析

调用DynamicLibrary.open()以打开形如es{algo}_{os}{bitness}.{ext}的文件名,这将使用操作系统的解析规则。

用户提供的解析

本包的用户可以选择在程序早期覆盖库路径。

提供的FFI编解码器有静态的getter/setter用于libraryPath。用户应在第一次使用前设置libraryPath。如果用户试图多次设置libraryPath,将会抛出StateError

final codec = ZstdCodec.libraryPath = '/path/to/shared/library.so';

签名

Windows

提供的dll已使用Instantiations, Inc拥有的MS Authenticode证书进行了数字签名。

Linux

N/A

Mac

提供的dylibs当前未签名,最近版本的OSX将拒绝加载它们,除非您允许它从“安全性与隐私”对话框中加载。

build脚本已提供blob_builder,您可以根据需要自行构建和签名。

Instantiations可能会在未来签署这些库,并将在变更日志和此处注明。

工具

tool子目录中,提供了以下工具。

Blob Builder

blob_builder是一个基于cmake的构建生成器,它构建所有预构建的共享库并将其复制到dart库的适当位置。

维护人员使用此工具更新预构建的共享库。它也可以用来通过调整定义版本级别信息的CMake变量来构建自定义版本的各种库。

预构建的共享库位于每个FFI编解码器实现的blobs目录中。对于名为xxx的编解码器,默认情况下,分发的共享库位于lib/src/xxx/blobs

CMakeLists.txt文件中有如何运行该工具的说明。

框架

初始提供的编解码器使用基于FFI的实现。然而,该框架轻松允许纯Dart实现在前端Web上下文中使用。rle_example.dart展示了如何实现这一点的一个简单示例。

Dart:io中的GZipCodec是理解如何将VAST平台框架抽象表示为Dart编解码器、转换器、过滤器、接收器的一个很好的起点。

主要的压缩框架抽象包括:

  • CodecConverter - 将压缩框架连接到dart:convert中的Converter
  • CodecFilter - 直接处理字节数据并提供低级压缩实现和钩子。
  • CodecSink - 一种类型的ByteConversionSink,用于高效传输字节数据。
  • CodecBuffer - 由原生或Dart堆字节支持的具有流式API的缓冲区。

特性和Bug

请在issue tracker中提交功能请求和Bug。

它们将由Instantiations, Inc以尽力而为的方式审查和处理。

关于我们

自1988年以来,Instantiations一直致力于构建软件以满足客户不断变化的需求。我们现在增加了Dart和Flutter到我们的工具箱中。

有关我们使用Dart、Flutter和其他语言的定制开发或咨询服务的更多信息,请访问:instantiations服务页面


更多关于Flutter文件压缩插件es_compression的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter文件压缩插件es_compression的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用es_compression插件进行文件压缩的示例代码。es_compression插件允许你在Flutter应用中轻松地进行文件压缩和解压缩。

1. 添加依赖

首先,你需要在你的pubspec.yaml文件中添加es_compression插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  es_compression: ^2.0.0  # 请检查最新版本号

然后运行flutter pub get来安装依赖。

2. 导入插件

在你的Dart文件中导入插件:

import 'package:es_compression/es_compression.dart';

3. 使用插件进行文件压缩

以下是一个简单的示例,演示如何使用es_compression插件来压缩一个文件:

import 'package:flutter/material.dart';
import 'package:es_compression/es_compression.dart';
import 'package:path_provider/path_provider.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('File Compression Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              // 获取临时目录
              final tempDir = await getTemporaryDirectory();
              final filePath = "${tempDir.path}/example.txt";
              final compressedFilePath = "${tempDir.path}/example.zip";

              // 写入示例文件内容
              await File(filePath).writeAsString('This is an example text file.');

              // 压缩文件
              try {
                await ESCompression.compressFile(filePath, compressedFilePath, 'zip');
                print('File compressed successfully to $compressedFilePath');
              } catch (e) {
                print('Error compressing file: $e');
              }
            },
            child: Text('Compress File'),
          ),
        ),
      ),
    );
  }
}

4. 运行应用

运行你的Flutter应用,点击按钮后,它会在临时目录中创建一个名为example.txt的文件,并将其压缩为example.zip

注意事项

  1. 权限:如果你的应用需要访问设备的存储,请确保在AndroidManifest.xmlInfo.plist中添加了相应的权限。
  2. 错误处理:在实际应用中,应该添加更多的错误处理逻辑来确保应用的健壮性。
  3. 依赖版本:确保你使用的是最新版本的es_compression插件,因为插件的API可能会随着版本更新而变化。

通过上述步骤,你可以在Flutter项目中成功使用es_compression插件进行文件压缩。

回到顶部