如何计算FTP上的目录大小?

时间:2010-07-02 09:41:39

标签: c# ftp

如何计算FTP文件夹的大小?你知道C#中的任何工具或编程方式吗?

10 个答案:

答案 0 :(得分:82)

如果你有FileZilla,你可以使用这个技巧:

  • 单击要计算其大小的文件夹
  • 点击Add files to queue

这将扫描所有文件夹和文件,并将它们添加到队列中。然后查看队列窗格及其下方(在状态栏上),您应该看到一条指示队列大小的消息。

答案 1 :(得分:14)

您可以在lftp中使用du命令用于此目的,如下所示:

echo "du -hs ." | lftp example.com 2>&1

这将打印当前目录的磁盘大小incl。所有子目录,采用人类可读的格式(-h)并省略子目录的输出行(-s)。使用2>&1将stderr输出重新路由到stdout,以便它包含在输出中。

但是,lftp是一个仅限Linux的软件,因此要在C#中使用它,您需要在Cygwin内使用它。

its manpage中缺少lftp du命令文档,但使用help du命令在lftp shell中可用。作为参考,我在这里复制它的输出:

lftp :~> help du
Usage: du [options] <dirs>
Summarize disk usage.
 -a, --all             write counts for all files, not just directories
     --block-size=SIZ  use SIZ-byte blocks
 -b, --bytes           print size in bytes
 -c, --total           produce a grand total
 -d, --max-depth=N     print the total for a directory (or file, with --all)
                       only if it is N or fewer levels below the command
                       line argument;  --max-depth=0 is the same as
                       --summarize
 -F, --files           print number of files instead of sizes
 -h, --human-readable  print sizes in human readable format (e.g., 1K 234M 2G)
 -H, --si              likewise, but use powers of 1000 not 1024
 -k, --kilobytes       like --block-size=1024
 -m, --megabytes       like --block-size=1048576
 -S, --separate-dirs   do not include size of subdirectories
 -s, --summarize       display only a total for each argument
     --exclude=PAT     exclude files that match PAT

答案 2 :(得分:4)

如果您只是需要完成工作,那么SmartFTP可以帮助您it also has a PHP and ASP script通过递归浏览所有文件来获取总文件夹大小。

答案 3 :(得分:3)

WinSCP(Microsoft Windows上的免费GUI):

enter image description here

enter image description here

答案 4 :(得分:2)

您可以发送LIST命令,该命令应该为您提供目录中的文件列表以及有关它们的一些信息(相当确定包含的大小),然后您可以解析并添加。

取决于您如何连接到服务器,但如果您使用的是WebRequest.Ftp类,则可使用ListDirectoryDetails方法执行此操作。有关详细信息,请参阅here;有关示例代码,请参阅here

请注意,如果您希望包含所有子目录的总大小,我认为您必须输入每个子目录并以递归方式调用它,因此它可能非常慢。它可能很慢,所以通常我建议,如果可能的话,在服务器上有一个脚本来计算大小并以某种方式返回结果(可能将它存储在你可以下载和读取的文件中)。

编辑:或者如果您只是意味着您对使用它的工具感到满意,我认为FlashFXP会这样做,而且可能还有其他高级FTP客户端。或者,如果它是一个unix服务器,我有一个模糊的内存,你只需登录并输入ls -laR或其他东西来获得递归目录列表。

答案 5 :(得分:1)

我使用来自Alex Pilotti的FTPS library和C#在一些生产环境中执行一些FTP命令。该库运行良好,但您必须以递归方式获取目录中的文件列表,并将它们的大小一起添加以获得结果。对于一些具有复杂文件结构的大型服务器(有时1-2分钟),这可能会耗费一些时间。

无论如何,这是我在他的库中使用的方法:

/// <summary>
/// <para>This will get the size for a directory</para>
/// <para>Can be lengthy to complete on complex folder structures</para>
/// </summary>
/// <param name="pathToDirectory">The path to the remote directory</param>
public ulong GetDirectorySize(string pathToDirectory)
{
    try
    {
        var client = Settings.Variables.FtpClient;
        ulong size = 0;

        if (!IsConnected)
            return 0;

        var dirList = client.GetDirectoryList(pathToDirectory);
        foreach (var item in dirList)
        {
            if (item.IsDirectory)
                size += GetDirectorySize(string.Format("{0}/{1}", pathToDirectory, item.Name));
            else
                size += item.Size;
        }
        return size;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    return 0;
}

答案 6 :(得分:1)

以最简单有效的方式获取FTP目录大小的所有内容递归。

  

var size = FtpHelper.GetFtpDirectorySize(&#34; ftpURL&#34;,&#34; userName&#34;,   &#34;密码&#34);

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;

public static class FtpHelper
{
    public static long GetFtpDirectorySize(Uri requestUri, NetworkCredential networkCredential, bool recursive = true)
    {
        //Get files/directories contained in CURRENT directory.
        var directoryContents = GetFtpDirectoryContents(requestUri, networkCredential);

        long ftpDirectorySize = default(long); //Set initial value of the size to default: 0
        var subDirectoriesList = new List<Uri>(); //Create empty list to fill it later with new founded directories.

        //Loop on every file/directory founded in CURRENT directory. 
        foreach (var item in directoryContents)
        {
            //Combine item path with CURRENT directory path.
            var itemUri = new Uri(Path.Combine(requestUri.AbsoluteUri + "\\", item));
            var fileSize = GetFtpFileSize(itemUri, networkCredential); //Get item file size.

            if (fileSize == default(long)) //This means it has no size so it's a directory and NOT a file.
                subDirectoriesList.Add(itemUri); //Add this item Uri to subDirectories to get it's size later.
            else //This means it has size so it's a file.
                Interlocked.Add(ref ftpDirectorySize, fileSize); //Add file size to overall directory size.
        }

        if (recursive) //If recursive true: it'll get size of subDirectories files.
            //Get size of selected directory and add it to overall directory size.
            Parallel.ForEach(subDirectoriesList, (subDirectory) => //Loop on every directory
        Interlocked.Add(ref ftpDirectorySize, GetFtpDirectorySize(subDirectory, networkCredential, recursive)));

        return ftpDirectorySize; //returns overall directory size.
    }
    public static long GetFtpDirectorySize(string requestUriString, string userName, string password, bool recursive = true)
    {
        //Initialize Uri/NetworkCredential objects and call the other method to centralize the code
        return GetFtpDirectorySize(new Uri(requestUriString), GetNetworkCredential(userName, password), recursive);
    }

    public static long GetFtpFileSize(Uri requestUri, NetworkCredential networkCredential)
    {
        //Create ftpWebRequest object with given options to get the File Size. 
        var ftpWebRequest = GetFtpWebRequest(requestUri, networkCredential, WebRequestMethods.Ftp.GetFileSize);

        try { return ((FtpWebResponse)ftpWebRequest.GetResponse()).ContentLength; } //Incase of success it'll return the File Size.
        catch (Exception) { return default(long); } //Incase of fail it'll return default value to check it later.
    }
    public static List<string> GetFtpDirectoryContents(Uri requestUri, NetworkCredential networkCredential)
    {
        var directoryContents = new List<string>(); //Create empty list to fill it later.
        //Create ftpWebRequest object with given options to get the Directory Contents. 
        var ftpWebRequest = GetFtpWebRequest(requestUri, networkCredential, WebRequestMethods.Ftp.ListDirectory);
        try
        {
            using (var ftpWebResponse = (FtpWebResponse)ftpWebRequest.GetResponse()) //Excute the ftpWebRequest and Get It's Response.
            using (var streamReader = new StreamReader(ftpWebResponse.GetResponseStream())) //Get list of the Directory Contentss as Stream.
            {
                var line = string.Empty; //Initial default value for line
                while (!string.IsNullOrEmpty(line = streamReader.ReadLine())) //Read current line of Stream.
                    directoryContents.Add(line); //Add current line to Directory Contentss List.
            }
        }
        catch (Exception) { throw; } //Do nothing incase of Exception occurred.
        return directoryContents; //Return all list of Directory Contentss: Files/Sub Directories.
    }
    public static FtpWebRequest GetFtpWebRequest(Uri requestUri, NetworkCredential networkCredential, string method = null)
    {
        var ftpWebRequest = (FtpWebRequest)WebRequest.Create(requestUri); //Create FtpWebRequest with given Request Uri.
        ftpWebRequest.Credentials = networkCredential; //Set the Credentials of current FtpWebRequest.

        if (!string.IsNullOrEmpty(method))
            ftpWebRequest.Method = method; //Set the Method of FtpWebRequest incase it has a value.
        return ftpWebRequest; //Return the configured FtpWebRequest.
    }
    public static NetworkCredential GetNetworkCredential(string userName, string password)
    {
        //Create and Return NetworkCredential object with given UserName and Password.
        return new NetworkCredential(userName, password);
    }
}

答案 7 :(得分:1)

如@FranckDernoncourt的回答所示,如果需要GUI工具,则可以使用WinSCP GUI。特别是它的folder properties dialog


如果需要代码,也可以使用WinSCP。尤其是对于WinSCP .NET assembly及其Session.EnumerateRemoteFiles method而言,很容易在包括C#在内的多种语言中实现。

它也可以通过内置的.NET FtpWebRequest来实现,但这需要做更多的工作。

两者均在How to get a directories file size from an FTP protocol in a .NET application中涵盖。

答案 8 :(得分:-1)

您可以使用FileZilla客户端。在此处下载:https://docs.swmansion.com/react-native-gesture-handler/docs/component-touchables

如果您想要更大的可读性,请访问:

编辑->设置->界面->文件大小格式->大小格式->使用SI符号选择二进制前缀。

选择目录后,您可以看到其大小。

https://filezilla-project.org/download.php?type=client

答案 9 :(得分:-2)

只需使用FTP“SIZE”命令......