Как рассчитать размер папки FTP? Знаете ли вы какой-либо инструмент или программный способ в С#?
Как рассчитать размер каталога на FTP?
Ответ 1
Если вам просто нужна работа, то SmartFTP может вам помочь, он также имеет PHP и ASP script, чтобы получить общий размер папки, рекурсивно просматривая все файлы.
Ответ 2
Если у вас есть FileZilla, вы можете использовать этот трюк:
- нажмите на папку (ы), размер которой вы хотите вычислить
- нажмите
Add files to queue
Это сканирует все папки и файлы и добавляет их в очередь. Затем посмотрите на панель очереди и под ней (в строке состояния) вы увидите сообщение с указанием размера очереди.
Ответ 3
Вы можете использовать команду du
в lftp
для этой цели, например:
echo "du -hs ." | lftp example.com 2>&1
Это будет печатать текущий размер диска диска, включая. все подкаталоги, в удобочитаемом формате (-h
) и опускание выходных строк для подкаталогов (-s
). Выход stderr перенаправляется на stdout с помощью 2>&1
, чтобы он включался в выход.
Однако lftp
- это программное обеспечение только для Linux, поэтому для его использования с С# вам нужно будет использовать его в 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
Вы можете отправить команду LIST
, которая должна предоставить вам список файлов в каталоге и некоторую информацию о них (достаточно уверен, что размер включен), которые вы могли бы проанализировать и добавить.
Зависит от того, как вы подключаетесь к серверу, но если вы используете класс WebRequest.Ftp
, там используется метод ListDirectoryDetails
. Подробнее см. здесь и здесь для примера кода.
Просто имейте в виду, что если вы хотите иметь общий размер, включая все подкаталоги, я думаю, вам придется вводить каждый подкаталог и вызывать его рекурсивно, чтобы он мог быть довольно медленным. Это может быть довольно медленным, поэтому я обычно рекомендую, если возможно, иметь script на сервере, вычислять размер и возвращать результат каким-то образом (возможно, хранить его в файле, который вы могли бы скачать и прочитать).
Изменить: Или, если вы просто хотите, чтобы вам понравился инструмент, который сделает это за вас, я думаю, что FlashFXP сделает это и, возможно, другие продвинутые клиенты FTP. Или, если это unix-сервер, у меня есть неопределенная память, которую вы можете просто войти и введите ls -laR
или что-то, чтобы получить список рекурсивных каталогов.
Ответ 5
Я использую библиотеку FTPS от Alex Pilotti с С# для выполнения некоторых команд 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
Простейший и эффективный способ получить размер каталога FTP со всем содержимым рекурсивно.
var size = FTP.GetFtpDirectorySize( "ftpURL", "userName", "password" );
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
public static class FTP
{
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 a directory and NOT a file.
subDirectoriesList.Add(itemUri); //Add this item Uri to subDirectories to get it size later.
else //This means it has size so it 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.
Parallel.ForEach(subDirectoriesList, (subDirectory) => //Loop on every directory
//Get size of selected directory and add it to overall directory size.
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 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.
do
{
line = streamReader.ReadLine(); //Read current line of Stream.
directoryContents.Add(line); //Add current line to Directory Contentss List.
} while (!string.IsNullOrEmpty(line)); //Keep reading while the line has value.
}
}
catch (Exception) { } //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
Просто используйте команду FTP "SIZE"...