You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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库完成解压:

  1. 先在pubspec.yaml中添加依赖:
dependencies:
  archive: ^3.4.10
  1. 实现代码:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 21:33:23