月別アーカイブ
検索

SharpSsh は.NET 環境で SSH 接続をするための ライブラリ です。

今回、とあるシステム開発のために、VC# で SFTP を行う必要があったので、使ってみました。

とても簡単に使えて便利なのですが、ファイル更新時刻を取得/設定できなかったので、それ用の関数を追加しました。

変更箇所

SharpSshはソースも公開されているので、簡単に機能追加ができます。

今回手を加えたのは、Sftp.cs というファイルです。public class Sftp のブロックの中に以下のコードを追加しました。


namespace Tamir.SharpSsh
{
  public class Sftp : SshTransferProtocolBase
  {
    (略)
        // MTime
        public int GetMTime(string path)
        {
          Tamir.SharpSsh.jsch.SftpATTRS attr;

            try
            {
              attr = SftpChannel.stat(path);
              return attr.getMTime();
            }
            catch (Exception e)
            {
              return 0;
            }
        }
        public void SetMTime(string path,int mtime)
        {
          try
          {
            SftpChannel.setMtime(path,mtime);
          }
          catch (Exception e)
          {
          }
        }

    (略)
  }
}

実はSharpSsh ライブラリのソース内では、SFTPの(たぶん)全ての機能を使えるように実装されているのですが、外部に公開されている関数がごく一部なのです。

なので、今回組んだのは機能を外部に提供する部分だけです。

使用上の注意

この機能(リモートファイルの更新時刻を取得/設定)を使いたかったのは、ローカルファイルのそれと比較してどちらか新しい方を残す、ということをしたかったのです。

ところが、.NET で使われるファイル更新時刻の表現方法は DateTime 型で、今回作ったGetMTime()関数とは異なる形式です。

DateTime 型は、1601/01/01 00:00:00 からの経過時間を 100ns で割った値です。

片やGetMTime()の戻り値はUNIX形式。つまり、1970/01/01 00:00:00 からの経過時間(秒)です。

そこで、DateTime 型を UNIX形式に変換する関数を作りました。


  static int DateTime2UnitTime(DateTime dt)
  {
    const long basetime = 116444736000000000L;
    // ( = DateTime(1970,1,1,9,0,0,0).ToFileTime() )
    return (int)((dt.ToFileTime() - basetime) / 10000000);
  }

basetime定数は、1970/01/01 09:00:00(DateTime が日本時間なので9時です。本来ならUTCに合わせて作るべきなのですが・・・)を ToFileTime()関数でlong型にしたもの。1601年から1970年までを、100ns単位で表したものです。

で、それを知りたいDateTimeから引いて、秒単位に直すと 目的のUNIX形式になる、というわけです。

他にも

他のSFTPの機能も簡単に実装できるので、そのうち作りたいと思います。

関係ありそうな記事

コメント