Как рассчитать размер каталога на FTP? - PullRequest
27 голосов
/ 02 июля 2010

Как рассчитать размер папки FTP? Знаете ли вы какой-либо инструмент или программный способ в C #?

Ответы [ 7 ]

82 голосов
/ 28 января 2012

Если у вас есть FileZilla, вы можете использовать этот трюк:

  • нажмите на папку (и), размер которых вы хотите рассчитать
  • нажмите Add files to queue

Это отсканирует все папки и файлы и добавит их в очередь. Затем посмотрите на панель очереди и под ней (в строке состояния) вы увидите сообщение с указанием размера очереди.

14 голосов
/ 20 июля 2014

Вы можете использовать команду du в lftp для этой цели, например:

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

Это напечатает размер диска текущего каталога вкл.все подкаталоги в удобочитаемом формате (-h) и пропущенные строки вывода для подкаталогов (-s).Вывод stderr перенаправляется в stdout с помощью 2>&1, поэтому он включается в вывод.

Однако lftp является программным обеспечением только для Linux, поэтому для его использования из C # вам потребуется использовать его в Cygwin .

Документация команды lftp du отсутствует в ее man-странице , но доступна в оболочке lftp с командой help du.Для справки, я скопирую его вывод здесь:

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
4 голосов
/ 03 июля 2010

Если вам просто нужна работа, то SmartFTP может вам помочь, также имеет скрипт PHP и ASP , чтобы получить общий размер папки путем рекурсивного просмотра всех файлов.

2 голосов
/ 02 июля 2010

Вы можете послать команду LIST, которая выдаст вам список файлов в каталоге и некоторую информацию о них (достаточно точно указан размер), который вы затем сможете разобрать и сложить.

Зависит от того, как вы подключаетесь к серверу, но если вы используете класс WebRequest.Ftp, для этого есть метод ListDirectoryDetails.См. здесь для подробной информации и здесь для некоторого примера кода.

Просто имейте в виду, если вы хотите иметь общий размер, включая все подкаталоги, я думаю, вынеобходимо войти в каждый подкаталог и вызвать его рекурсивно, чтобы он мог быть довольно медленным.Это может быть довольно медленным, поэтому обычно я рекомендую, если возможно, чтобы скрипт на сервере вычислял размер и каким-то образом возвращал результат (возможно, сохраняя его в файле, который вы могли бы скачать и прочитать).

Редактировать: Или, если вы просто хотите сказать, что вас порадует инструмент, который сделает это за вас, я думаю, что FlashFXP сделает это, и, вероятно, подойдут и другие продвинутые FTP-клиенты.Или, если это сервер Unix, у меня есть неопределенная память, которую вы можете просто войти в систему и набрать ls -laR или что-то еще, чтобы получить рекурсивный список каталогов.

1 голос
/ 09 ноября 2017

Самый простой и эффективный способ получить размер каталога FTP со всем его содержимым рекурсивно.

var size = FtpHelper.GetFtpDirectorySize ("ftpURL", "userName", "Пароль");

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);
    }
}
1 голос
/ 11 июня 2012

Я использую библиотеку FTPS от Алекса Пилотти с 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;
}
0 голосов
/ 18 февраля 2011

Просто используйте команду FTP "SIZE" ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...