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

从Blob Storage提取tar.gz并上传至另一Blob Storage时文件为0字节的问题

问题:提取Tar.gz文件后上传至Azure Blob Storage得到0字节文件

问题背景

从Azure Blob Storage读取tar.gz文件,本地解压到文件夹正常,但尝试将解压结果上传至另一个Blob Storage时,得到0字节的Blob文件,无报错信息。

本地可用代码:

var blobEndPointSrc = "https://storageaccountname.blob.core.windows.net/data-source-raw?etc...";
var blobContainerClientSrc = GetBlobServiceClientSAS(blobEndPointSrc);
var blobClientSrc = blobContainerClientSrc.GetBlobClient("file.tar.gz");
var blobDownloadInfo = blobClientSrc.OpenRead();
using Stream gzipStream = new GZipInputStream(blobDownloadInfo);

// 本地解压正常
using var tarArchive = TarArchive.CreateInputTarArchive(gzipStream);
tarArchive.ExtractContents(@"D:\file");

尝试上传的错误代码:

// using var tarArchive = TarArchive.CreateInputTarArchive(gzipStream);
// tarArchive.ExtractContents(@"D:\file");

var tarBuffer = TarBuffer.CreateInputTarBuffer(gzipStream);
Stream result = new MemoryStream();
TarBuffer.CreateOutputTarBuffer(result);

var blobEndPointDst = = "https://storageaccountname2.blob.core.windows.net/data-source-raw?etc...";
var blobContainerClientDst = GetBlobServiceClientSAS(blobEndPointDst);
var blobClientDst = blobContainerClient1.GetBlobClient("extracted_file");
blobClientDst.Upload(result, true);

错误原因

  1. 未执行实际内容读写:仅初始化了TarBuffer,但未读取源tar文件的条目内容并写入输出流,导致MemoryStream为空。
  2. 流位置未重置:即使写入内容,上传前未将MemoryStream的Position设为0,上传时从流末尾读取,最终上传0字节。
  3. 代码笔误:blobEndPointDst = =多了一个等号;blobClientDst使用了错误的容器客户端blobContainerClient1(应为blobContainerClientDst)。

修正方案

方案1:逐个上传解压后的文件(对应本地解压到文件夹场景)

遍历tar.gz中的每个文件条目,直接将条目内容上传至目标Blob Storage,无需本地存储:

var blobEndPointSrc = "https://storageaccountname.blob.core.windows.net/data-source-raw?etc...";
var blobContainerClientSrc = GetBlobServiceClientSAS(blobEndPointSrc);
var blobClientSrc = blobContainerClientSrc.GetBlobClient("file.tar.gz");
using var blobDownloadStream = blobClientSrc.OpenRead();
using var gzipStream = new GZipInputStream(blobDownloadStream);
using var tarArchive = TarArchive.CreateInputTarArchive(gzipStream);

// 初始化目标Blob容器客户端
var blobEndPointDst = "https://storageaccountname2.blob.core.windows.net/data-source-raw?etc...";
var blobContainerClientDst = GetBlobServiceClientSAS(blobEndPointDst);

// 绑定进度事件,处理每个文件条目上传
tarArchive.ProgressMessageEvent += (sender, args) =>
{
    var entry = args.TarEntry;
    if (!entry.IsDirectory)
    {
        // 以tar条目名称作为Blob名称创建客户端
        var blobClientDst = blobContainerClientDst.GetBlobClient(entry.Name);
        // 打开条目内容流并上传
        using var entryStream = entry.OpenEntryStream();
        blobClientDst.Upload(entryStream, overwrite: true);
    }
};

// 触发提取流程,自动调用事件处理上传
tarArchive.ExtractContents();

方案2:将解压内容重新打包为Tar后上传

如果需要将所有解压文件重新打包成单个Tar文件上传,可直接通过流复制,避免本地内存占用:

var blobEndPointSrc = "https://storageaccountname.blob.core.windows.net/data-source-raw?etc...";
var blobContainerClientSrc = GetBlobServiceClientSAS(blobEndPointSrc);
var blobClientSrc = blobContainerClientSrc.GetBlobClient("file.tar.gz");
using var blobDownloadStream = blobClientSrc.OpenRead();
using var gzipStream = new GZipInputStream(blobDownloadStream);
using var inputTarArchive = TarArchive.CreateInputTarArchive(gzipStream);

// 初始化目标Blob客户端
var blobEndPointDst = "https://storageaccountname2.blob.core.windows.net/data-source-raw?etc...";
var blobContainerClientDst = GetBlobServiceClientSAS(blobEndPointDst);
var blobClientDst = blobContainerClientDst.GetBlobClient("extracted_file.tar");

// 直接打开Blob的写入流,边读边写
using var uploadStream = blobClientDst.OpenWrite(overwrite: true);
using var outputTarArchive = TarArchive.CreateOutputTarArchive(uploadStream);

// 遍历输入Tar的条目,复制到输出Tar
inputTarArchive.ProgressMessageEvent += (sender, args) =>
{
    var entry = args.TarEntry;
    if (!entry.IsDirectory)
    {
        outputTarArchive.WriteEntry(entry, recurse: true);
    }
};

inputTarArchive.ExtractContents();
outputTarArchive.Close(); // 确保所有内容写入上传流

推荐替代库

.NET原生System.IO.Compression

无需第三方依赖,.NET 6及以上版本支持TarReader/TarWriter,API更简洁稳定:

var blobEndPointSrc = "https://storageaccountname.blob.core.windows.net/data-source-raw?etc...";
var blobContainerClientSrc = GetBlobServiceClientSAS(blobEndPointSrc);
var blobClientSrc = blobContainerClientSrc.GetBlobClient("file.tar.gz");
using var blobDownloadStream = blobClientSrc.OpenRead();
using var gzipStream = new GZipStream(blobDownloadStream, CompressionMode.Decompress);
using var tarReader = new TarReader(gzipStream);

var blobEndPointDst = "https://storageaccountname2.blob.core.windows.net/data-source-raw?etc...";
var blobContainerClientDst = GetBlobServiceClientSAS(blobEndPointDst);

TarEntry entry;
while ((entry = tarReader.GetNextEntry()) != null)
{
    if (!entry.IsDirectory)
    {
        var blobClientDst = blobContainerClientDst.GetBlobClient(entry.Name);
        using var entryStream = entry.OpenEntryStream();
        blobClientDst.Upload(entryStream, overwrite: true);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 13:29:59