flutter 解压 zip 中文乱码问题处理

前言

很简单的一个 zip 包解压缩的功能,但是 windows 平台中文显示乱码,很糟心,搜了一圈没找到现成的方法,在此贴上我的解决方式。

实现

导入需要的包

复制代码
flutter pub add archive

flutter pub add fast_gbk

flutter pub add path

代码如下:

dart 复制代码
import 'dart:io';
import 'package:fast_gbk/fast_gbk.dart';
import 'package:archive/archive.dart';
import 'package:path/path.dart' as p;

void main() {
  unzip('G:/testUpdate/111.zip', 'G:/testUpdate/1');
}

void unzip(String inputPath, String outputPath) {
  var archive = zipDecode(inputPath);

  for (final file in archive) {
    final filename = file.name;
    final filePath = p.join(outputPath, filename);

    if (!file.isFile && !file.isSymbolicLink) {
      Directory(filePath).createSync(recursive: true);
      continue;
    }

    if (file.isSymbolicLink) {
      final link = Link(filePath);
      link.createSync(p.normalize(file.nameOfLinkedFile), recursive: true);
    } else {
      final data = file.content as List<int>;
      final newFile = File(filePath);
      newFile.createSync(recursive: true);
      newFile.writeAsBytesSync(data);
    }
  }
}

// 由于 archive 包直接用会乱码,这里加一下对于 gbk 编码的处理
Archive zipDecode(String inputPath) {
  final zipFile = File(inputPath);
  final bytes = zipFile.readAsBytesSync();
  final inputStream = InputStream(bytes);
  // final inputStream = InputFileStream('G:/testUpdate/111.zip');
  var directory = ZipDirectory.read(inputStream);

  final archive = Archive();

  for (final zfh in directory.fileHeaders) {
    final zf = zfh.file!;

    // The attributes are stored in base 8
    final mode = zfh.externalFileAttributes!;
    final compress = zf.compressionMethod != ZipFile.STORE;

    //dynamic content = zf.rawContent;
    var file = ArchiveFile(
        zf.filename, zf.uncompressedSize!, zf, zf.compressionMethod);

    file.mode = mode >> 16;

    // see https://github.com/brendan-duncan/archive/issues/21
    // UNIX systems has a creator version of 3 decimal at 1 byte offset
    if (zfh.versionMadeBy >> 8 == 3) {
      file.isFile = false;

      final fileType = file.mode & 0xF000;
      switch (fileType) {
        case 0x8000:
        case 0x0000: // No determination can be made so we assume it's a file.
          file.isFile = true;
          break;
        case 0xA000:
          file.isSymbolicLink = true;
          break;
        default:
      }
    } else {
      file.isFile = !file.name.endsWith('/');
    }

    file.crc32 = zf.crc32;
    file.compress = compress;
    file.lastModTime = zf.lastModFileDate << 16 | zf.lastModFileTime;

    final needGbkDecode = zf.flags & 2048 == 0;
    if (needGbkDecode) {
      file.name = gbk.decode(zf.filename.codeUnits);
    }

    archive.addFile(file);
  }

  return archive;
}

昨天刚接触的 flutter,若是代码有问题还望指出,非常感谢!

相关推荐
zilikew9 小时前
Flutter框架跨平台鸿蒙开发——今日吃啥APP的开发流程
flutter·华为·harmonyos·鸿蒙
Whisper_Sy9 小时前
Flutter for OpenHarmony移动数据使用监管助手App实战 - 应用列表实现
android·开发语言·javascript·flutter·php
血色橄榄枝9 小时前
03 基于Flutter集成网络请求On OpenHarmony
网络·flutter
小风呼呼吹儿10 小时前
Flutter 框架跨平台鸿蒙开发 - 虚拟拼豆图纸查看应用开发教程
flutter·华为·harmonyos
IT陈图图10 小时前
Flutter × OpenHarmony 跨端实践:从零构建一个轻量级视频播放器
flutter·音视频·鸿蒙·openharmony
Miguo94well10 小时前
Flutter框架跨平台鸿蒙开发——戒拖延APP的开发流程
flutter·华为·harmonyos·鸿蒙
2601_9494800611 小时前
Flutter for OpenHarmony 音乐播放器App实战 - 主题设置实现
windows·flutter
小风呼呼吹儿11 小时前
Flutter 框架跨平台鸿蒙开发 - 虚拟红包雨应用开发教程
flutter·华为·harmonyos
2501_9445215915 小时前
Flutter for OpenHarmony 微动漫App实战:主题配置实现
android·开发语言·前端·javascript·flutter·ecmascript
时光慢煮15 小时前
Flutter × OpenHarmony 跨端开发实战:动态显示菜单详解
flutter·华为·开源·openharmony