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

如何计算Azure共享文件中添加JSON后的新Zip归档文件大小?

解决Azure中Zip归档大小计算与调整问题

问题背景

流程为:输入Zip归档 → 解压至Azure共享文件夹 → 添加JSON文件 → 重新打包为包含原数据+JSON的新Zip。核心痛点是无法准确计算新归档的最终大小,也无法调整文件大小去除无效空白空间。

当前困境

  • 用原归档大小×1.5 + JSON长度估算maxSize,但因原归档压缩率未知,估算误差极大;
  • 直接求和解压目录所有文件大小不可行:小文件(如单字符TXT)打包后的Zip大小会超过文件总和,且解压时会触发「归档大小与负载块不匹配」错误;
  • 尝试过创建0大小结果文件,压缩时计算大小再通过SetHttpHeaders调整,但未成功。

解决方案

核心思路:通过内存流中转压缩,先获取准确大小再上传

避免直接在Azure文件流上创建ZipArchive(需要预指定大小),先在本地MemoryStream中完成压缩,拿到精确的最终大小后,再创建对应大小的Azure文件并写入数据,彻底解决预估算的问题。

修改后的代码实现

private async Task<ShareFileClient> CreateNewArchive(ShareDirectoryClient rootDirectory, string fileName, ShareDirectoryClient extractDirectory)
{
    // 先在内存流中完成Zip压缩,获取准确大小
    using var memoryStream = new MemoryStream();
    using (var zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, leaveOpen: true))
    {
        foreach (var item in extractDirectory.GetFilesAndDirectories())
            await CreateFromAny(zipArchive, item, extractDirectory, string.Empty);
    }
    
    // 获取压缩后的准确大小
    long finalSize = memoryStream.Length;
    var resultFile = rootDirectory.GetFileClient(fileName);
    
    // 创建对应大小的Azure文件并写入数据
    var options = new ShareFileOpenWriteOptions { MaxSize = finalSize };
    await using var azureStream = await resultFile.OpenWriteAsync(true, 0, options);
    memoryStream.Position = 0;
    await memoryStream.CopyToAsync(azureStream);
    await azureStream.FlushAsync();
    
    return resultFile;
}

private async Task CreateFromAny(ZipArchive archive, ShareFileItem entry, ShareDirectoryClient sourceDir, string currentPath)
{
    if (entry.IsDirectory)
    {
        await CreateFromDirectory(archive, sourceDir.GetSubdirectoryClient(entry.Name), currentPath);
    }
    else
    {
        var path = Path.Combine(currentPath, entry.Name);
        var extractedFile = sourceDir.GetFileClient(entry.Name);
        await using (var fileZip = archive.CreateEntry(path).Open())
        {
            await using (var entryStream = await extractedFile.OpenReadAsync())
            {
                await entryStream.CopyToAsync(fileZip);
                await entryStream.FlushAsync();
            }
            await fileZip.FlushAsync();
        }
    }
}

private async Task CreateFromDirectory(ZipArchive archive, ShareDirectoryClient sourceDir, string currentPath)
{
    currentPath = Path.Combine(currentPath, sourceDir.Name);
    archive.CreateEntry($"{currentPath}/");
    foreach (var file in sourceDir.GetFilesAndDirectories())
        await CreateFromAny(archive, file, sourceDir, currentPath);
}

方案优势

  1. 完全准确的大小计算:通过MemoryStream中转,直接获取压缩后的真实长度,无需估算;
  2. 避免Azure文件的空白空间:创建文件时直接指定最终大小,不会产生无效空白块;
  3. 解决解压报错问题:因为最终文件大小与实际压缩数据完全匹配,不会出现「归档大小与负载块不匹配」的错误。

内容的提问来源于stack exchange,提问作者embolshov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 00:42:53