web-dev-qa-db-ja.com

FtpWebRequestを使用したファイルのダウンロード

FtpWebRequestを使用してファイルをダウンロードしようとしています。

private void DownloadFile(string userName, string password, string ftpSourceFilePath, string localDestinationFilePath)
{
    int bytesRead = 0;
    byte[] buffer = new byte[1024];

    FtpWebRequest request = CreateFtpWebRequest(ftpSourceFilePath, userName, password, true);
    request.Method = WebRequestMethods.Ftp.DownloadFile;

    Stream reader = request.GetResponse().GetResponseStream();
    BinaryWriter writer = new BinaryWriter(File.Open(localDestinationFilePath, FileMode.CreateNew));

    while (true)
    {
        bytesRead = reader.Read(buffer, 0, buffer.Length);

        if (bytesRead == 0)
            break;

        writer.Write(buffer, 0, bytesRead);
    }        
}

私が作成したこのCreateFtpWebRequestメソッドを使用します。

private FtpWebRequest CreateFtpWebRequest(string ftpDirectoryPath, string userName, string password, bool keepAlive = false)
{
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(ftpDirectoryPath));

    //Set proxy to null. Under current configuration if this option is not set then the proxy that is used will get an html response from the web content gateway (firewall monitoring system)
    request.Proxy = null;

    request.UsePassive = true;
    request.UseBinary = true;
    request.KeepAlive = keepAlive;

    request.Credentials = new NetworkCredential(userName, password);

    return request;
}

ダウンロードします。しかし、情報は常に破損しています。誰が何が起こっているのか知っていますか?

8
Rick Eyre

ちょうどそれを理解しました:

    private void DownloadFile(string userName, string password, string ftpSourceFilePath, string localDestinationFilePath)
    {
        int bytesRead = 0;
        byte[] buffer = new byte[2048];

        FtpWebRequest request = CreateFtpWebRequest(ftpSourceFilePath, userName, password, true);
        request.Method = WebRequestMethods.Ftp.DownloadFile;

        Stream reader = request.GetResponse().GetResponseStream();
        FileStream fileStream = new FileStream(localDestinationFilePath, FileMode.Create);

        while (true)
        {
            bytesRead = reader.Read(buffer, 0, buffer.Length);

            if (bytesRead == 0)
                break;

            fileStream.Write(buffer, 0, bytesRead);
        }
        fileStream.Close();       
    }

代わりにFileStreamを使用する必要がありました。

25
Rick Eyre

最も簡単な方法

.NET Frameworkを使用してFTPサーバーからファイルをダウンロードする最も簡単な方法は、 WebClient.DownloadFileメソッド を使用することです。

WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
client.DownloadFile(
    "ftp://ftp.example.com/remote/path/file.Zip", @"C:\local\path\file.Zip");

高度なオプション

FtpWebRequest class を使用します。より高度な制御のみが必要な場合は、そのWebClientクラスは提供しません( TLS/SSL暗号化 のように、進行状況監視など)。簡単な方法は、 Stream.CopyTo メソッドを使用してFTP応答ストリームをFileStreamにコピーすることです。

FtpWebRequest request =
    (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.Zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.DownloadFile;

using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(@"C:\local\path\file.Zip"))
{
    ftpStream.CopyTo(fileStream);
}

進捗状況の監視

ダウンロードの進行状況を監視する必要がある場合は、コンテンツをチャンクごとに自分でコピーする必要があります。

FtpWebRequest request =
    (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.Zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.DownloadFile;

using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(@"C:\local\path\file.Zip"))
{
    byte[] buffer = new byte[10240];
    int read;
    while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        fileStream.Write(buffer, 0, read);
        Console.WriteLine("Downloaded {0} bytes", fileStream.Position);
    }
}

GUIの進行状況(WinForms ProgressBar)については、以下を参照してください。
ProgressBarを使用したFtpWebRequest FTPダウンロード


ダウンロードフォルダ

リモートフォルダからすべてのファイルをダウンロードする場合は、を参照してください。
C#FTP経由ですべてのファイルとサブディレクトリをダウンロード

9
Martin Prikryl