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

如何使用ShareDirectoryClient移动Azure文件共享目录并压缩

如何对Azure文件共享中通过ShareDirectoryClient操作的目录实现压缩?

已实现的目录移动代码

我已成功使用ShareDirectoryClient完成Azure文件共享中目录的移动操作,相关代码如下:

using System;
using System.Threading.Tasks;
using Azure.Storage.Files.Shares;

namespace SO69798149
{
    class Program
    {
        const string MyconnectionString = "DefaultEndpointsProtocol=https;AccountName=account-name;AccountKey=account-key";
        const string MyshareName = "share-name";
        const string SourceDirectoryName = "source-directory-name";
        private const string RenamedDirectoryName = "new-directory-name";
        
        static async Task Main(string[] args)
        {
            ShareClient myshare = new ShareClient(MyconnectionString, MyshareName);
            ShareDirectoryClient sourceDirectoryClient = myshare.GetDirectoryClient(SourceDirectoryName);
            ShareDirectoryClient targetDirectoryClient = myshare.GetDirectoryClient(RenamedDirectoryName);
            await RenameDirectory(sourceDirectoryClient, targetDirectoryClient);
            Console.WriteLine("Directory renamed.");
            
            // 调用压缩方法
            await CompressAzureDirectory(targetDirectoryClient, myshare.GetFileClient("compressed-directory.zip"));
        }

        static async Task RenameDirectory(ShareDirectoryClient sourceDirectoryClient,
            ShareDirectoryClient targetDirectoryClient)
        {
            // 创建目标目录
            await targetDirectoryClient.CreateIfNotExistsAsync();
            // 列出源目录下的所有文件和子目录
            var result = sourceDirectoryClient.GetFilesAndDirectoriesAsync();
            await foreach (var items in result.AsPages())
            {
                foreach (var item in items.Values)
                {
                    if (item.IsDirectory)
                    {
                        // 递归处理子目录
                        await RenameDirectory(sourceDirectoryClient.GetSubdirectoryClient(item.Name),
                            targetDirectoryClient.GetSubdirectoryClient(item.Name));
                    }
                    else
                    {
                        // 复制文件到目标目录后删除源文件
                        var sourceFileClient = sourceDirectoryClient.GetFileClient(item.Name);
                        var targetFileClient = targetDirectoryClient.GetFileClient(item.Name);
                        await targetFileClient.StartCopyAsync(sourceFileClient.Uri);
                        await sourceFileClient.DeleteIfExistsAsync();
                    }
                }
            }
            // 删除源目录
            await sourceDirectoryClient.DeleteIfExistsAsync();
        }
        
    }
}

压缩尝试遇到的问题

尝试使用System.IO.Compression.ZipFile进行压缩时,执行以下代码:

using System.IO.Compression;
ZipFile.CreateFromDirectory(sourceDirectoryClient.Path, targetDirectoryClient.Path);

出现错误:Could not find a part of the path '/app/NewFolder/test.zip'.

我也了解到可以使用SharpZipLib库,其示例代码如下:

Zipping a directory using C# and SharpZipLib

void fastcompressDirectory(string DirectoryPath, string OutputFilePath, int CompressionLevel = 9)
{
    ICSharpCode.SharpZipLib.Zip.FastZip z = new ICSharpCode.SharpZipLib.Zip.FastZip();
    z.CreateEmptyDirectories = true;
    z.CreateZip(OutputFilePath, DirectoryPath, true, "");

    if (File.Exists(OutputFilePath))
        Console.WriteLine("D0ne");
    else
        Console.WriteLine("Failed");
}

问题原因

无论是ZipFile.CreateFromDirectory还是SharpZipLib的FastZip.CreateZip,都是针对本地文件系统路径设计的,而ShareDirectoryClient.Path返回的是Azure文件共享中的逻辑路径(并非本地磁盘路径),因此这些方法无法直接识别和访问Azure上的目录内容,导致路径找不到的错误。

解决方案:本地临时目录中转压缩

要实现Azure文件共享目录的压缩,需要先将目录内容下载到本地临时目录,压缩后再上传回Azure文件共享,具体实现如下:

方法1:使用原生System.IO.Compression实现

添加以下异步压缩方法到你的代码中:

using System.IO;
using System.IO.Compression;

static async Task CompressAzureDirectory(ShareDirectoryClient sourceDirClient, ShareFileClient targetZipFileClient)
{
    // 创建本地临时目录
    string tempLocalDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
    Directory.CreateDirectory(tempLocalDir);

    try
    {
        // 递归下载Azure目录到本地临时目录
        await DownloadDirectoryToLocal(sourceDirClient, tempLocalDir);

        // 压缩本地临时目录到临时zip文件
        string tempZipPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".zip");
        ZipFile.CreateFromDirectory(tempLocalDir, tempZipPath, CompressionLevel.Optimal, includeBaseDirectory: false);

        // 将压缩后的zip文件上传到Azure文件共享
        using (var stream = File.OpenRead(tempZipPath))
        {
            await targetZipFileClient.UploadAsync(stream, overwrite: true);
        }

        Console.WriteLine("Directory compressed and uploaded successfully.");
    }
    finally
    {
        // 清理本地临时文件和目录
        if (Directory.Exists(tempLocalDir))
            Directory.Delete(tempLocalDir, recursive: true);
        foreach (var file in Directory.GetFiles(Path.GetTempPath(), "*.zip"))
        {
            File.Delete(file);
        }
    }
}

static async Task DownloadDirectoryToLocal(ShareDirectoryClient dirClient, string localDirPath)
{
    // 创建本地目录
    Directory.CreateDirectory(localDirPath);

    // 列出当前Azure目录下的所有项
    var items = dirClient.GetFilesAndDirectoriesAsync();
    await foreach (var page in items.AsPages())
    {
        foreach (var item in page.Values)
        {
            if (item.IsDirectory)
            {
                // 递归下载子目录
                var subDirClient = dirClient.GetSubdirectoryClient(item.Name);
                string subLocalDir = Path.Combine(localDirPath, item.Name);
                await DownloadDirectoryToLocal(subDirClient, subLocalDir);
            }
            else
            {
                // 下载文件到本地
                var fileClient = dirClient.GetFileClient(item.Name);
                string localFilePath = Path.Combine(localDirPath, item.Name);
                await fileClient.DownloadToAsync(localFilePath);
            }
        }
    }
}

方法2:使用SharpZipLib实现

  1. 先安装SharpZipLib NuGet包:Install-Package ICSharpCode.SharpZipLib
  2. 添加以下压缩方法:
using ICSharpCode.SharpZipLib.Zip;

static async Task CompressAzureDirectoryWithSharpZipLib(ShareDirectoryClient sourceDirClient, ShareFileClient targetZipFileClient)
{
    string tempLocalDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
    Directory.CreateDirectory(tempLocalDir);

    try
    {
        await DownloadDirectoryToLocal(sourceDirClient, tempLocalDir);

        string tempZipPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".zip");
        FastZip fastZip = new FastZip();
        fastZip.CreateEmptyDirectories = true;
        // 压缩本地目录到zip文件
        fastZip.CreateZip(tempZipPath, tempLocalDir, true, "");

        // 上传zip到Azure
        using (var stream = File.OpenRead(tempZipPath))
        {
            await targetZipFileClient.UploadAsync(stream, overwrite: true);
        }

        Console.WriteLine("Directory compressed with SharpZipLib and uploaded successfully.");
    }
    finally
    {
        // 清理本地资源
        if (Directory.Exists(tempLocalDir))
            Directory.Delete(tempLocalDir, recursive: true);
        foreach (var file in Directory.GetFiles(Path.GetTempPath(), "*.zip"))
        {
            File.Delete(file);
        }
    }
}

使用方式

在Main方法中,目录移动完成后调用对应的压缩方法即可:

// 使用原生ZipFile压缩
await CompressAzureDirectory(targetDirectoryClient, myshare.GetFileClient("target-directory.zip"));

// 或者使用SharpZipLib压缩
// await CompressAzureDirectoryWithSharpZipLib(targetDirectoryClient, myshare.GetFileClient("target-directory-sharp.zip"));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 05:45:21