c# - Asp.Net Azure Cloud - 获取文件大小需要很长时间

标签 c# .net azure cloud

我想获取父文件夹下可用的各个子文件夹下的所有文件的大小总和。

我得到了大小,但计算结果需要大约 15 秒。

这是代码:

var storageAccount = CloudStorageAccount.Parse("connectionString");
var fileClient = storageAccount.CreateCloudFileClient();
var cloudFileShare = fileClient.GetShareReference("shareName");
var rootDirectory = cloudFileShare.GetRootDirectoryReference();
var directory = rootDirectory.GetDirectoryReference("folderName");

var size = directory.ListFilesAndDirectories().Select(x => (CloudFileDirectory)x).SelectMany(x => x.ListFilesAndDirectories()).Sum(x => ((CloudFile)x).Properties.Length);

我可以进一步优化它以快速获得大小吗?

编辑1:

测试:

  • 场景 1:包含更多或更少文件的更多文件夹
  • 场景 2:文件夹较少,文件较多或较少

调查结果:

  • 当文件夹数量较多时,无论文件多少,都需要很长时间 计数(可多可少)
  • 当文件夹数量较少时,无论文件数量如何(可能更多或更少),它都可以正常工作

最佳答案

检查您的 LINQ 查询:

var size = directory
           .ListFilesAndDirectories()
           .Select(x => (CloudFileDirectory)x)
           .SelectMany(x => x.ListFilesAndDirectories())
           .Sum(x => ((CloudFile)x).Properties.Length);

我可以看到一些初步问题。首先,这假设根目录内的第一层仅存在目录。这可以通过类型转换 (CloudFileDirectory)x 看出。 。如果CloudFile,这将引发异常而是找到了。可扩展的解决方案应该处理这两种类型的文件。其次,此查询还假设每个子目录中仅存在文件,因此 (CloudFile)x铸件。这意味着这只会深入子目录的一层,并且不会递归任何子目录。如果找到任何子目录,这也会引发异常。我在下面概述了一些更具可扩展性的方法。

解决方案 1:

使用 CloudFileDirectory.ListFilesAndDirectories() ,它将所有文件组合成 IEnumerable<IListFileItem> 。如果找到文件,则递归遍历每个项目并总结找到的 btyes;如果找到目录,则递归。

public static void FileShareByteCount(CloudFileDirectory directory, ref long bytesCount)
{
    if (directory == null)
    {
        throw new ArgumentNullException("directory", "Directory cannot be null");
    }

    var files = directory.ListFilesAndDirectories();

    foreach (var item in files)
    {
        if (item.GetType() == typeof(CloudFileDirectory))
        {
            var cloudFileDirectory = item as CloudFileDirectory;
            FileShareByteCount(cloudFileDirectory, ref bytesCount);
        }
        else if (item.GetType() == typeof(CloudFile))
        {
            var cloudFile = item as CloudFile;
            bytesCount += cloudFile.Properties.Length;
        }
    }
}

用法1:

long bytesCount = 0;
FileShareByteCount(sampleDir, ref bytesCount);
Console.WriteLine($"Current file share usage: {bytesCount}");

解决方案 2:

使用 CloudFileDirectory.ListFilesAndDirectoriesSegmented() 批量浏览文件共享,它允许您指定每个IEnumerable<IListFileItem>返回的文件数。部分。与上面相同,如果找到文件,则递归遍历每一项,并对找到的 btyes 求和;如果找到目录,则递归。

public static void FileShareByteCount(CloudFileDirectory directory, int? maxResults, ref long bytesCount)
{
    if (directory == null)
    {
        throw new ArgumentNullException("directory", "Directory cannot be null");
    }

    FileContinuationToken continuationToken = null;

    do
    {
        var resultSegment = directory.ListFilesAndDirectoriesSegmented(maxResults, continuationToken, null, null);

        var results = resultSegment.Results;

        if (results.Count() > 0)
        {
            foreach (var item in results)
            {
                if (item.GetType() == typeof(CloudFileDirectory))
                {
                    var cloudFileDirectory = item as CloudFileDirectory;
                    FileShareByteCount(cloudFileDirectory, maxResults, ref bytesCount);
                }
                else if (item.GetType() == typeof(CloudFile))
                {
                    var cloudFile = item as CloudFile;
                    bytesCount += cloudFile.Properties.Length;
                }
            }
        }

        continuationToken = resultSegment.ContinuationToken;

    } while (continuationToken != null);
}

用法2:

long bytesCount = 0;
FileShareByteCount(directory, 100, ref bytesCount);
Console.WriteLine($"Current file share usage: {bytesCount}");

注意:您可以使用 maxResults 指定段的最大大小。 。微软documentation状态:

A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000.

关于c# - Asp.Net Azure Cloud - 获取文件大小需要很长时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59854797/

相关文章:

c# - 与发布配置文件名称相关的 ASP.NET web.config 转换

c# - 使用 C# 更改显示属性

.net - 使用 ASP.NET MVC 身份验证的 "Remember me"不起作用

c# - 如何将数字字符串排序为数字?

c# - 我们是在反汇编程序中查看原始代码还是在逆向工程 CIL 中查看?

c# - 具有透明状态栏的 Xamarin Forms 背景图像

c# - 如何裁剪 PDF 页面

azure 二头肌 : setting a null value if the property doesn't exist

Azure 表存储 - 表服务查询检索并返回 10 个实体,直到最后一个实体

azure - 在 azure 逻辑应用程序中,如何从 azure 服务总线主题的死信队列中检索消息