如何在Flutter/Dart中拆分tar.gz文件为多个JSON文件?
在Dart/Flutter中实现tar.gz文件拆分并生成JSON文件
完全可行,根据你的需求方向,分两种场景给出实现方案:
场景1:模拟split -b 1800k的二进制拆分,将块存为JSON文件
split命令是直接按字节切割二进制文件,但JSON无法直接存储二进制数据,因此需要将每个二进制块转成Base64编码后存入JSON。实现代码如下:
import 'dart:io'; import 'dart:convert'; Future<void> splitTarGzToJson(String sourcePath, int chunkSizeKB) async { final file = File(sourcePath); final fileSize = await file.length(); final chunkSize = chunkSizeKB * 1024; // 转换为字节单位 final baseName = file.path.split('.').take(2).join('_'); // 提取原文件名前缀 // 流式读取文件,避免大文件占用过多内存 final stream = file.openRead(); int chunkIndex = 1; List<int> currentChunk = []; await for (final bytes in stream) { currentChunk.addAll(bytes); while (currentChunk.length >= chunkSize) { // 截取当前块数据 final chunk = currentChunk.sublist(0, chunkSize); currentChunk = currentChunk.sublist(chunkSize); // 构造JSON内容,用Base64存储二进制块 final jsonContent = jsonEncode({ 'chunk_index': chunkIndex, 'chunk_data': base64Encode(chunk), 'total_chunks': (fileSize / chunkSize).ceil() }); // 写入对应JSON文件 await File('${baseName}_$chunkIndex.json').writeAsString(jsonContent); chunkIndex++; } } // 处理剩余的不足一个块的数据 if (currentChunk.isNotEmpty) { final jsonContent = jsonEncode({ 'chunk_index': chunkIndex, 'chunk_data': base64Encode(currentChunk), 'total_chunks': (fileSize / chunkSize).ceil() }); await File('${baseName}_$chunkIndex.json').writeAsString(jsonContent); } } // 使用示例 void main() async { await splitTarGzToJson('file_name.tar.gz', 1800); }
场景2:先解压tar.gz,再拆分内容为JSON文件
如果你的目标是先提取tar.gz内的内容(比如内部是一个大JSON文件),再拆分成多个小JSON文件,需要借助archive库完成解压:
- 先在
pubspec.yaml中添加依赖:
dependencies: archive: ^3.4.10
- 实现代码:
import 'dart:io'; import 'dart:convert'; import 'package:archive/archive.dart'; Future<void> extractAndSplitToJson(String sourcePath, int splitCount) async { // 读取并解压tar.gz文件 final bytes = File(sourcePath).readAsBytesSync(); final archive = GZipDecoder().decodeBytes(bytes); final tarArchive = TarDecoder().decodeBytes(archive); // 假设tar包内只有一个目标JSON文件,取第一个非目录文件 final jsonFile = tarArchive.files.firstWhere((f) => !f.isDirectory); final jsonContent = utf8.decode(jsonFile.content); final data = jsonDecode(jsonContent); // 若内容是数组,按指定数量拆分 if (data is List) { final chunkSize = (data.length / splitCount).ceil(); for (int i = 0; i < splitCount; i++) { final start = i * chunkSize; final end = (i + 1) * chunkSize > data.length ? data.length : (i + 1) * chunkSize; final chunk = data.sublist(start, end); await File('file_name_${i+1}.json').writeAsString(jsonEncode(chunk)); } } else { // 若内容是单个对象,可按需按字段拆分,此处示例直接写入单个文件 await File('file_name_1.json').writeAsString(jsonContent); } } // 使用示例 void main() async { await extractAndSplitToJson('file_name.tar.gz', 3); // 拆分为3个JSON文件 }
注意事项
- 处理超大文件时,场景1的流式读取方式更内存友好;场景2若解压后内容过大,建议改用流式解压与处理逻辑。
- 还原拆分后的JSON文件时,需读取每个JSON的Base64数据,解码后拼接为原tar.gz文件(场景1),或直接合并JSON内容(场景2)。
内容的提问来源于stack exchange,提问作者Ravi Patel
相关产品推荐
相关产品推荐

