4

FTP サーバー上の各ファイルのファイル名、ファイル サイズ、および最終更新時刻を取得し、それを listView に入力したいと考えています。

FTP ホストを切り替えるまでは非常にうまく機能していましたが、新しいホストが実際の FTP クライアントと同じくらい高速であるにもかかわらず、今では非常に遅くなりました。

理由について明確な理由はありますか?

また、毎回ログイン資格情報を送信する必要がありますか?

最初のメソッドを使用して文字列配列を取得し、それを反復処理して、各項目で 2 番目のメソッドを使用してファイル サイズを取得しています。

    public static string[] GetFileList()
    {
        string[] downloadFiles;
        StringBuilder result = new StringBuilder();
        FtpWebRequest request;
        try
        {
            request = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://mysite.se/"));
            request.UseBinary = true;
            request.Credentials = new NetworkCredential(settings.Username, settings.Password);
            request.Method = WebRequestMethods.Ftp.ListDirectory;
            request.UseBinary = true;

            WebResponse response = request.GetResponse();
            StreamReader reader = new StreamReader(response.GetResponseStream());

            string line = reader.ReadLine();
            while (line != null)
            {
                result.Append(line);
                result.Append("\n");
                line = reader.ReadLine();
            }
            // to remove the trailing '\n'
            result.Remove(result.ToString().LastIndexOf('\n'), 1);
            reader.Close();
            response.Close();
            return result.ToString().Split('\n');
        }
        catch (Exception ex)
        {
            System.Windows.Forms.MessageBox.Show(ex.Message);
            downloadFiles = null;
            return downloadFiles;
        }
    }

    public static int GetFileSize(string file)
    {
        //MessageBox.Show("getting filesize...");

        StringBuilder result = new StringBuilder();
        FtpWebRequest request;
        try
        {
            request = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://mysite.se/" + file));
            request.UseBinary = true;
            request.Credentials = new NetworkCredential(settings.Username, settings.Password);
            request.Method = WebRequestMethods.Ftp.GetFileSize;

            int dataLength = (int)request.GetResponse().ContentLength;

            return dataLength;
        }
        catch (Exception ex)
        {
            //System.Windows.Forms.MessageBox.Show(ex.Message);
            return 1337;
        }
    }
4

3 に答える 3

7

問題は、GetFileSize 呼び出しごとにサーバーに再接続し、ファイル サイズの要求を発行する必要があることです。単一の永続的な接続を使用するように設定できれば、接続時間を節約できますが、それでも各ファイルの要求を送信して応答を待つのに多くの時間を費やすことになります。

(編集: これはすでに当てはまる可能性があります。MSDN によると:複数の FtpWebRequests は、可能であれば既存の接続を再利用します。 )

ListDirectory ではなく ListDirectoryDe​​tails を使用すると、サーバーはおそらく、各ファイル名とともに、より多くの情報 (ファイル サイズ、アクセス許可など) を送信します。これは、ListDirectory を実行するよりも長くはかからず、各行から名前とサイズを取り出して、後で使用するためにサイズを保存することができます。

ただし、サーバーによって情報が異なる形式で送信されたり、サイズ情報がまったく送信されない場合があるため、プログラムで FTP サーバーを確実に使用する必要がある場合、これは役に立たない可能性があります。

于 2010-02-20T16:36:27.050 に答える
4

正しくない、または良い答えでさえありません:

これがどのように機能するかを示す PowerShell テストの例を次に示します。

$request=[System.Net.FtpWebRequest]::Create('ftp://ftp.hp.com/control/SavvisLoad.whp-ftp.xml')
$request.UseBinary=$false
$request.Method=[System.Net.WebRequestMethods+Ftp]::GetDateTimestamp
$request.GetResponse()

これは、HP パブリック サーバーを使用し、ファイル サイズを取得する方法を示しています。

ListDirectoryDe​​tailsはフォルダ情報を取得します。

上記の最大のエラーは、モードが Binary に設定されていることです。すべてのディレクトリ リストとファイル情報は、テキスト モードを使用する必要があります。

于 2012-11-30T23:34:43.817 に答える
1

これは、ディレクトリリストを取得するための実証済みの高速な方法です。PowerShellを使用してそのままテストできます。

[System.Net.FtpWebRequest]$request = [System.Net.WebRequest]::Create("ftp://ftp.hp.com/control")
#$request.Credentials=New-Object System.Net.NetworkCredential('Anonymous','johnjones3@msn.com')
$request.Method = [System.Net.WebRequestMethods+FTP]::ListDirectoryDetails
$request.UseBinary=$false
$response=$request.GetResponse()
$stream=$response.GetResponseStream()
$b=new-object byte[] 1024
$stream.Read($b,0,$b.Count)
$b|%{$s+=[char]$_}
$s
于 2012-11-30T23:56:49.483 に答える