Flutter压缩解压插件flutter_minizip_ffi_bindings的使用
Flutter压缩解压插件flutter_minizip_ffi_bindings的使用
flutter_minizip_ffi_bindings
是一个用于在 Flutter 中进行文件压缩和解压的插件。它通过 FFI(Foreign Function Interface)绑定到 zlib-ng/minizip-ng
库,从而允许你在 Dart 代码中调用 C 函数。
注意事项
这个包不包含 minizip
的二进制库。你需要自行构建 libminizip
并将其添加到你的应用项目或示例项目中。
在 Android 上运行示例
- 构建你的 Android
libminizip
。- 你可以使用 build_minizip_mobile 这个工具来帮助你构建。
- 将构建好的
libminizip.so
文件复制到以下路径:example/android/app/src/main/jniLibs/ ├── arm64-v8a │ └── libminizip.so ├── armeabi-v7a │ └── libminizip.so ├── x86 │ └── libminizip.so └── x86_64 └── libminizip.so
- 执行以下命令运行示例:
cd example && flutter run
在 iOS 上运行示例
- 构建你的 iOS
libminizip
。- 你可以使用 build_minizip_mobile 这个工具来帮助你构建。
- 将构建好的
libminizip.3.0.dylib
和include/
目录复制到以下路径:example/ios/Runner/minizip/ ├── include │ ├── mz.h │ ... │ └── mz_zip_rw.h └── libminizip.3.0.dylib
- 执行以下命令运行示例:
cd example && flutter run
在你的应用项目中使用此插件
- 在
pubspec.yaml
文件中将此包作为开发依赖项添加:dev_dependencies: flutter_minizip_ffi_bindings: ^x.y.z
- 构建你的
libminizip
并将其添加到你的应用的原生项目中。- 你可以使用 build_minizip_mobile 这个工具来帮助你构建。
- 导入插件:
import 'package:flutter_minizip_ffi_bindings/flutter_minizip_ffi_bindings.dart';
完整示例代码
以下是完整的示例代码,展示了如何使用 flutter_minizip_ffi_bindings
插件来列出和读取 ZIP 文件中的文件。
import 'dart:convert';
import 'dart:ffi' as ffi;
import 'dart:io';
import 'package:ffi/ffi.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter_minizip_ffi_bindings/flutter_minizip_ffi_bindings.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
const _sampleDataName = 'minizip-ng-master.zip';
Future<void> _copySampleData() async {
final sampleData = await rootBundle.load('assets/$_sampleDataName');
final filesDir = await getApplicationSupportDirectory();
final dstPath = p.join(filesDir.path, _sampleDataName);
final dst = File(dstPath);
await dst.writeAsBytes(sampleData.buffer.asUint8List());
}
final _minizip = () {
final lib = Platform.isIOS
? ffi.DynamicLibrary.process()
: ffi.DynamicLibrary.open('libminizip.so');
return Minizip(lib);
}();
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await _copySampleData();
runApp(const _App());
}
[@immutable](/user/immutable)
class _App extends StatelessWidget {
const _App({
Key? key,
}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('flutter_minizip_ffi_bindings_example'),
),
body: const _Body(),
),
);
}
}
[@immutable](/user/immutable)
class _Body extends StatefulWidget {
const _Body({
Key? key,
}) : super(key: key);
[@override](/user/override)
_BodyState createState() => _BodyState();
}
class _BodyState extends State<_Body> {
List<String>? _paths;
Future<void> _listFilesInZip() async {
final filesDir = await getApplicationSupportDirectory();
final path = p.join(filesDir.path, _sampleDataName);
final handle = calloc<ffi.Pointer<ffi.Void>>();
_minizip.mz_zip_reader_create(handle);
_minizip.mz_zip_reader_open_file(handle.value, path.toNativeUtf8().cast());
final paths = <String>[];
_minizip.mz_zip_reader_goto_first_entry(handle.value);
do {
if (_minizip.mz_zip_reader_entry_is_dir(handle.value) == MZ_OK) {
continue;
}
final info = calloc<ffi.Pointer<mz_zip_file_s>>();
_minizip.mz_zip_reader_entry_get_info(handle.value, info);
paths.add(info.value.ref.filename.cast<Utf8>().toDartString());
} while (_minizip.mz_zip_reader_goto_next_entry(handle.value) == MZ_OK);
_minizip.mz_zip_reader_close(handle.value);
_minizip.mz_zip_reader_delete(handle);
setState(() => _paths = paths);
}
[@override](/user/override)
void initState() {
super.initState();
_listFilesInZip();
}
[@override](/user/override)
Widget build(BuildContext context) {
final _paths = this._paths;
if (_paths == null) {
return const Center(
child: CircularProgressIndicator(),
);
}
return Scrollbar(
child: ListView.builder(
itemCount: _paths.length,
itemBuilder: (context, index) {
return _ListTile(path: _paths[index]);
},
),
);
}
}
[@immutable](/user/immutable)
class _ListTile extends StatelessWidget {
const _ListTile({
required this.path,
Key? key,
}) : super(key: key);
final String path;
[@override](/user/override)
Widget build(BuildContext context) {
return DecoratedBox(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Theme.of(context).dividerColor,
),
),
),
child: ListTile(
title: Text(path),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return _Detail(path: path);
},
),
);
},
),
);
}
}
[@immutable](/user/immutable)
class _Detail extends StatelessWidget {
const _Detail({
required this.path,
Key? key,
}) : super(key: key);
final String path;
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(path),
),
body: _Content(path: path),
);
}
}
[@immutable](/user/immutable)
class _Content extends StatelessWidget {
const _Content({
required this.path,
Key? key,
}) : super(key: key);
final String path;
Future<List<String>> _readFileInZip(String filePath) async {
final filesDir = await getApplicationSupportDirectory();
final path = p.join(filesDir.path, _sampleDataName);
final handle = calloc<ffi.Pointer<ffi.Void>>();
_minizip.mz_zip_reader_create(handle);
_minizip.mz_zip_reader_open_file(handle.value, path.toNativeUtf8().cast());
_minizip.mz_zip_reader_locate_entry(
handle.value,
filePath.toNativeUtf8().cast(),
0,
);
final info = calloc<ffi.Pointer<mz_zip_file_s>>();
_minizip.mz_zip_reader_entry_get_info(handle.value, info);
final len = info.value.ref.uncompressed_size;
final buf = calloc<ffi.Uint8>(len);
_minizip.mz_zip_reader_entry_open(handle.value);
_minizip.mz_zip_reader_entry_read(handle.value, buf.cast(), len);
final bytes = List<int>.from(buf.asTypedList(len));
_minizip.mz_zip_reader_entry_close(handle.value);
_minizip.mz_zip_reader_close(handle.value);
_minizip.mz_zip_reader_delete(handle);
final lines = () {
try {
return const Utf8Decoder().convert(bytes);
} catch (e) {
return 'Error: Invalid UTF-8 Strings';
}
}();
return const LineSplitter().convert(lines);
}
[@override](/user/override)
Widget build(BuildContext context) {
return FutureBuilder<List<String>>(
future: _readFileInZip(path),
builder: (context, snapshot) {
final lines = snapshot.data;
if (snapshot.connectionState != ConnectionState.done || lines == null) {
return const Center(
child: CircularProgressIndicator(),
);
}
return Scrollbar(
child: SafeArea(
child: ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: lines.length,
itemBuilder: (context, index) {
return Text(lines[index]);
},
),
),
);
},
);
}
}
更多关于Flutter压缩解压插件flutter_minizip_ffi_bindings的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter压缩解压插件flutter_minizip_ffi_bindings的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flutter_minizip_ffi_bindings
是一个 Flutter 插件,用于在 Flutter 应用中压缩和解压缩文件。它基于 minizip
库,并通过 FFI (Foreign Function Interface) 在 Flutter 中调用原生代码。
以下是如何在 Flutter 项目中使用 flutter_minizip_ffi_bindings
插件的基本步骤:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 flutter_minizip_ffi_bindings
插件的依赖:
dependencies:
flutter:
sdk: flutter
flutter_minizip_ffi_bindings: ^1.0.0 # 请检查最新版本
然后运行 flutter pub get
以获取依赖。
2. 导入插件
在需要使用压缩或解压缩功能的 Dart 文件中导入插件:
import 'package:flutter_minizip_ffi_bindings/flutter_minizip_ffi_bindings.dart';
3. 压缩文件
使用 MinizipFFI.compressFiles
方法可以将多个文件压缩到一个 ZIP 文件中:
void compressFiles() async {
List<String> filesToCompress = [
'/path/to/file1.txt',
'/path/to/file2.txt',
];
String outputZipPath = '/path/to/output.zip';
try {
await MinizipFFI.compressFiles(filesToCompress, outputZipPath);
print('文件压缩成功: $outputZipPath');
} catch (e) {
print('文件压缩失败: $e');
}
}
4. 解压缩文件
使用 MinizipFFI.extractFiles
方法可以将 ZIP 文件解压缩到指定目录:
void extractFiles() async {
String zipFilePath = '/path/to/input.zip';
String outputDirectory = '/path/to/output/directory';
try {
await MinizipFFI.extractFiles(zipFilePath, outputDirectory);
print('文件解压缩成功: $outputDirectory');
} catch (e) {
print('文件解压缩失败: $e');
}
}