web-dev-qa-db-fra.com

Comment calculer la taille du répertoire sur FTP?

Comment calculer la taille du dossier FTP? Connaissez-vous un outil ou un moyen de programmation en C #? 

26
jlp

Si vous avez juste besoin de travail, alors SmartFTP peut vous aider, il dispose également des scripts PHP et ASP pour obtenir la taille totale du dossier en parcourant tous les fichiers de manière récursive.

4
zengr

Si vous avez FileZilla, vous pouvez utiliser cette astuce:

  • cliquez sur le (s) dossier (s) dont vous voulez calculer la taille
  • cliquez sur Add files to queue

Cela analysera tous les dossiers et fichiers et les ajoutera à la file d'attente. Ensuite, examinez le volet de la file d’attente et un message indiquant la taille de la file d’attente apparaît en dessous (dans la barre d’état).

81
janusman

Vous pouvez utiliser la commande du dans lftp à cette fin, comme ceci:

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

Ceci imprimera la taille de disque du répertoire actuel, incl. tous les sous-répertoires, au format lisible par l'homme (-h) et en omettant les lignes de sortie pour les sous-répertoires (-s). La sortie de stderr est redirigée vers stdout avec 2>&1 de sorte qu'elle soit incluse dans la sortie.

Cependant, lftp est un logiciel exclusivement Linux. Par conséquent, pour l’utiliser en C #, vous devez l’utiliser dans Cygwin .

La documentation de la commande lftp du est absente de sa page de manuel , mais est disponible dans le shell lftp avec la commande help du. Pour référence, je copie sa sortie ici:

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
14
tanius

Vous pouvez envoyer la commande LIST qui devrait vous donner une liste de fichiers dans le répertoire et quelques informations à leur sujet (la taille est bien comprise), que vous pourrez ensuite analyser et additionner.

Cela dépend de la façon dont vous vous connectez au serveur, mais si vous utilisez la classe WebRequest.Ftp, il existe la méthode ListDirectoryDetails pour le faire. Voir ici pour plus de détails et ici pour un exemple de code.

Sachez simplement que si vous souhaitez avoir la taille totale, y compris tous les sous-répertoires, vous devrez entrer chaque sous-répertoire et l'appeler de manière récursive pour qu'il soit assez lent. Cela peut être assez lent, alors normalement, j’avais recommandé, si possible, d’avoir un script sur le serveur pour calculer la taille et renvoyer le résultat (éventuellement en le stockant dans un fichier que vous pourriez télécharger et lire).

Edit: Ou si vous voulez simplement dire que vous seriez satisfait d’un outil qui le fait pour vous, je pense que FlashFXP le fait et que d’autres clients FTP avancés le feront probablement aussi. Ou si c'est un serveur unix, j'ai une mémoire vague que vous pourriez simplement vous connecter et tapez ls -laR ou quelque chose pour obtenir une liste de répertoire récursive.

2
Hans Olsson

J'utilise la bibliothèque FTPS de Alex Pilotti avec C # pour exécuter certaines commandes FTP dans quelques environnements de production. La bibliothèque fonctionne bien, mais vous devez obtenir récursivement une liste de fichiers du répertoire et additionner leurs tailles pour obtenir le résultat. Cela peut prendre un peu de temps sur certains de nos plus gros serveurs (parfois 1-2 min) avec des structures de fichiers complexes. 

Quoi qu'il en soit, c'est la méthode que j'utilise avec sa bibliothèque:

/// <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;
}
1
jsmith

Le moyen le plus simple et le plus efficace d'obtenir la taille d'un répertoire FTP avec tout son contenu de manière récursive.

var size = FtpHelper.GetFtpDirectorySize ("ftpURL", "nom d'utilisateur", "mot de passe");

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
Ahmed Sabry