トップC# > FTPサーバーへのファイルのアップロード

FTPサーバーへのファイルのアップロード

1.WebClientクラスのUploadFileメソッド

ファイルのアップロードはC#では簡単である。 ID、パスワードでアクセス管理されているFTPサイトへアップロードするには、次のようにすればよい。

 WebClient wc = new WebClient();
 wc.Credentials = new NetworkCredential("id", "password");
 wc.UploadFile(uri, localpath);

NetworkCredentialコンストラクタの引数にはアクセス権のあるIDとパスワードを文字列型で与える。

2.ディレクトリの作成とディレクトリ/ファイルの削除

ディレクトリの作成の方が少し面倒である。 アップロードと同じWebClientクラスのインスタンスで実行できた方がありがたいのであるが、 マニュアルをざっとみた限りでは、該当機能が見つからなかった。

WebRequestクラスを使って、次のようにする。

ディレクトリの削除はMethodプロパティに WebRequestMethods.Ftp.RemoveDirectory を指定する。

ファイルの削除はMethodプロパティに WebRequestMethods.Ftp.DeleteFile を指定する。

 WebRequest request = WebRequest.Create(uri);
 request.Method = WebRequestMethods.Ftp.MakeDirectory;
 request.Credentials = new NetworkCredential("id", "password");
 using (var resp = (FtpWebResponse)request.GetResponse()) {
     Console.WriteLine(resp.StatusCode);
 }

3.アップロードプログラム

FTPサイトのディレクトリやファイルの照合は行わず、 前回アップロードを実行した時刻以降に作成、更新したファイルのみアップロードしている。 新たなディレクトリがあれば、FTPサイトに作成している。

したがって、ディレクトリやファイルの削除には対応していない。 これは、削除が少ないことと、削除に対応するとプログラムの実行時間が長くなることによる。

新規ディレクトリが見つかると、ファイルのアップロードとは別に ディレクトリ毎にWebRequestインスタンスを生成して、FTPサイトにディレクトリを作成している。 多くの新規ディレクトリが存在する場合、効率が悪いことになるが、実際の運用では、 ファイルの新規作成や更新が殆どであり、ディレクトリの作成はごくまれなため、問題にならない。

// upload.cs  2020.3.21/2013.3.9
// 前回アップロードした時刻以降で更新または作成された
// ファイルをサーバーにアップロードする。
// csc /out:c:\gis\bin\upload.exe c:\gis\src\upload.cs

using System;
using System.IO;
using System.Net;

class Upload {
    const string DIR = @"c:\www";
    const string TimeStampFile = "c:/gisstat/timestamp.dat";
    string srv, id, pw;
    DateTime dtLast;
    WebClient wc;

    public Upload() {
        Console.Write("password:");
        pw = Console.ReadLine();                            // パスワード入力
        if (File.Exists(TimeStampFile)) {
            dtLast = File.GetLastWriteTime(TimeStampFile);  // 前回のアップロード時間
            File.SetLastWriteTime(TimeStampFile, DateTime.Now);  // タイムスタンプ更新
        } else {
            dtLast = new DateTime(1,1,1);
            File.WriteAllText(TimeStampFile, "");
        }
        try {
            srv = "ftp://サーバー名";
            id = "ID";
            wc = new WebClient();
            wc.Credentials = new NetworkCredential(id, pw);
            scan(DIR);
            wc.Dispose();
        } catch (Exception e) {
            Console.WriteLine(e);
        }
    }

    void scan(string dir) {
        foreach (string path in Directory.GetFiles(dir)) {
            string uri = srv + path.Substring(DIR.Length).Replace(@"\", "/");
            DateTime dtCR = Directory.GetCreationTime(path);
            DateTime dtLW = Directory.GetLastWriteTime(path);
            if (dtCR > dtLast || dtLW > dtLast) {  // 更新または新規ファイル
                try {
                    byte[] response = wc.UploadFile(uri, path);
                    Console.WriteLine("upload: " + path + " " 
                        + System.Text.Encoding.ASCII.GetString(response));
                } catch (Exception e) {
                    System.Windows.Forms.MessageBox.Show(e.ToString());
                }
            }
        }
        foreach (string path in Directory.GetDirectories(dir)) {
            if (path == "c:\\www\\www08") continue;
            string uri = srv + path.Substring(DIR.Length).Replace(@"\", "/");
            DateTime dt  = Directory.GetCreationTime(path);
            if (dt > dtLast) {
                Console.WriteLine("新規ディレクトリ: " + uri);
                try {
                    WebRequest request = WebRequest.Create(uri);
                    request.Method = WebRequestMethods.Ftp.MakeDirectory;
                    request.Credentials = new NetworkCredential(id, pw);
                    using (var resp = (FtpWebResponse)request.GetResponse()) {
                        Console.WriteLine(resp.StatusCode);
                    }
                } catch (Exception ex) {
                    Console.WriteLine(ex);
                }
            }
            scan(path);
        }
    }

    static void Main() {
        new Upload();
        System.Threading.Thread.Sleep(1000);
    }

}