3

私は現在、サーバーへのファイルの一部の自動バックアップを実行するための小さな.NETコンソールアプリケーションを作成しています。私が直面している問題は、私が自分の側で悪天候に見舞われ、それが電力とネットワークの停止につながったことです。この間、ファイルのかなりの部分が通過しなかったか、破損していることに気づきました。もう一方の端にあるフォルダのサイズを取得して、ファイル名、ファイル数、およびディレクトリの合計サイズが一致するかどうかを確認する方法があるかどうか疑問に思いました。ファイルを転送する方法としてWinSCPとNcFTPを試しましたが、適切なファイルサイズを取得することに関しては何も見ていません。

これはほとんどWindowsからWindowsへの転送であるため、FTPクライアントを介してサイズを返すコマンドライン引数がある場合は、それは素晴らしいことです。

4

3 に答える 3

2

ディレクトリサイズを取得するための標準のFTPコマンドはありません。

すべてのサブディレクトリとファイルを再帰的に繰り返し、サイズを合計する必要があります。

これは、FTPプロトコルでファイル属性を使用してディレクトリリストを取得する唯一の移植可能な方法であるコマンドをFtpWebRequestサポートしていないため、.NETFramework/では簡単ではありません。MLSD

LISTコマンド( )を使用しListDirectoryDetailsて、サーバー固有のリストを解析するだけです。多くのFTPサーバーは*nixスタイルのリストを使用します。しかし、多くのサーバーは異なるフォーマットを使用しています。次の例では、*nix形式を使用しています。

static long CalculateFtpDirectorySize(string url, NetworkCredential credentials)
{
    FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(url);
    listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
    listRequest.Credentials = credentials;

    List<string> lines = new List<string>();

    using (var listResponse = (FtpWebResponse)listRequest.GetResponse())
    using (Stream listStream = listResponse.GetResponseStream())
    using (StreamReader listReader = new StreamReader(listStream))
    {
        while (!listReader.EndOfStream)
        {
            lines.Add(listReader.ReadLine());
        }
    }

    long result = 0;
    foreach (string line in lines)
    {
        string[] tokens =
            line.Split(new[] { ' ' }, 9, StringSplitOptions.RemoveEmptyEntries);
        string name = tokens[8];
        string permissions = tokens[0];

        string fileUrl = url + name;

        if (permissions[0] == 'd')
        {
            result += CalculateFtpDirectorySize(fileUrl + "/", credentials);
        }
        else
        {
            result += long.Parse(tokens[4]);
        }
    }

    return result;
}

次のように使用します。

var credentials = new NetworkCredential("username", "password");
long size = CalculateFtpDirectorySize("ftp://ftp.example.com/", credentials);

サーバーがDOS/Windowsリスト形式を使用している場合は、 C#クラスを参照してWebRequestMethods.Ftp.ListDirectoryDe​​tailsFTP応答を解析してください


MLSDまたは、最新のコマンドをサポートするサードパーティのFTPクライアント実装を使用することもできます。

たとえば、WinSCP.NETアセンブリはそれをサポートしています。

また、ディレクトリサイズの計算を簡単にする便利なSession.EnumerateRemoteFiles方法もあります。

var opts = EnumerationOptions.AllDirectories;
var files = session.EnumerateRemoteFiles("/", null, opts);
long size = files.Select(fileInfo => fileInfo.Length).Sum();

完全なコードは次のようになります。

SessionOptions sessionOptions = new SessionOptions
{
    Protocol = Protocol.Ftp,
    HostName = "ftp.example.com",
    UserName = "username",
    Password = "password",
};

using (Session session = new Session())
{
    // Connect
    session.Open(sessionOptions);

    var opts = EnumerationOptions.AllDirectories;
    var files = session.EnumerateRemoteFiles("/", null, opts);
    long size = files.Select(fileInfo => fileInfo.Length).Sum();
}

(私はWinSCPの作者です)

于 2017-09-04T19:29:59.877 に答える
1

「このディレクトリ内のファイルの合計サイズ」を要求する標準的な方法はありません。を介して各ファイルサイズを個別に要求することも、ディレクトリ全体SIZE file.txtを要求しls -lてファイルサイズを解析することもできます。

于 2011-10-25T16:58:57.757 に答える
0

最善の策は、ファイルの完全なリストを取得してから、一度に1つずつ送信することだと思います。転送中に接続が失敗した場合、そのファイルのアップロードは失敗します。ファイルのアップロードが成功した場合は、そのファイル名をリストから削除できます。

タグでNETについて言及したように、おそらくここでC#で実行する方法の例を探す必要があります。VB.Netも同様ですが、アイデアが得られます。

ここに示すように、ディレクトリリストを取得できます。

于 2011-10-26T07:17:05.673 に答える