Orion SSH-2 を使用してput/get

APIにput/getがないので、bufferをread/writeすることになります。

import java.io.File;
import java.io.IOException;

import org.apache.log4j.Logger;

import com.trilead.ssh2.Connection;
import com.trilead.ssh2.ConnectionMonitor;

/**
 * SSH-2接続をサポートするクラスです。<br>
 */
public class SshConnection implements ConnectionMonitor {

    private static final Logger log = Logger.getLogger(SftpOperator.class);
    /** 接続リトライ数 */
    private int retry;
    /** 接続リトライ間隔(msec) */
    private long waitMillis;


    // TODO どう使う?
    @Override
    public void connectionLost(Throwable throwable) {
        log.info("SSH: lost connection!");
    }


    /**
     * コンストラクタです。
     */
    public SshConnection(int retry, long waitMillis) {
        this.retry = retry;
        this.waitMillis = waitMillis;
    }


    /**
     * IDパス認証で接続します。
     */
    public Connection connect(String host, int port, String user, String password) throws IOException {
        return connect(host, port, user, password, null, null);
    }
    /**
     * 鍵認証で接続します。
     */
    public Connection connect(String host, int port, String user, String keyfileName, String keyfilePass) throws IOException {
        return connect(host, port, user, null, keyfileName, keyfilePass);
    }
    /*
     * 接続します。
     */
    private Connection connect(String host, int port, String user, String password, String keyfileName, String keyfilePass) throws IOException {
        Exception returnException = null;
        boolean isAuthenticated = false;
        Connection connection = null;
        log.debug("connect to " + user + "@" + host + ", retry=" + this.retry + "times, wait=" + this.waitMillis + "msec");
        for (int i = 0; i < this.retry; i++) {
            // リトライ処理
            returnException = null;
            try {
                // connect時の ServerHostKeyVerifier は、nullのためHostKeyはチェックされない
                connection = new Connection(host, port);
                connection.connect();
                if (keyfileName == null || keyfileName.isEmpty()) {
                    log.debug("IDパス認証");
                    isAuthenticated = connection.authenticateWithPassword(user, password);
                } else {
                    log.debug("鍵認証");
                    isAuthenticated = connection.authenticateWithPublicKey(user, new File(keyfileName), keyfilePass);
                }
                break; // 認証処理が行われた。

            } catch (Exception e) {
                log.info("connect failed:" + e.toString());
                returnException = e;
            }
            if (this.waitMillis > 0L && i < (this.retry - 1)) {
                try {
                    log.trace("wait:" + this.waitMillis + "msec");
                    Thread.sleep(this.waitMillis);
                } catch (InterruptedException ie) {;}
            }
        }
        if (returnException != null) {throw new IOException("接続失敗:", returnException);}
        if (!isAuthenticated) {throw new IOException("認証失敗");}
        return connection;
    }
}
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.log4j.Logger;

import com.trilead.ssh2.Connection;
import com.trilead.ssh2.SFTPException;
import com.trilead.ssh2.SFTPv3Client;
import com.trilead.ssh2.SFTPv3FileAttributes;
import com.trilead.ssh2.SFTPv3FileHandle;


/**
 * SFTP クライアントクラスです。<br>
 */
public class SftpOperator {

    private static final Logger log = Logger.getLogger(SftpOperator.class);

    /**
     * SFTP クライアントを生成します。<br>
     */
    public static SFTPv3Client creat(Connection connection) throws IOException {
        return new SFTPv3Client(connection);
    }

    /**
     * リモートファイルを取得します。<br>
     * ローカルファイルには受信可能であること。
     * @param sftp SFTPv3Client
     * @param remoteFileName リモートファイル名(パス含む)
     * @param localFileName ローカルファイル名(パス含む)
     */
    public static boolean get(final SFTPv3Client sftp, final String remoteFileName, final String localFileName) {
        // リモートファイルチェック
        long remoteFileLength = 0L;
        try {
            SFTPv3FileAttributes attributes = sftp.stat(remoteFileName);
            if (attributes.isDirectory()) {
                log.warn("リモートファイル(" + remoteFileName + ")はディレクトリ");
                return false;
            }
            remoteFileLength = sftp.stat(remoteFileName).size.longValue();
        } catch (IOException ioe) {
            log.warn("リモートファイル(" + remoteFileName + ")エラー:" + ioe.toString());
            return false;
        }
        // open remote file with read only
        SFTPv3FileHandle sftpFileHandle = null;
        try {
            sftpFileHandle = sftp.openFileRO(remoteFileName);
        } catch (IOException ioe) {
            log.warn("リモートファイル(" + remoteFileName + ") open error:" + ioe);
            return false;
        }
        // remoteFile read -> localFile write
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(localFileName));
            byte[] buffer = new byte[1024 * 8]; // No more than 32768 bytes may be read at once.
            long offset = 0;
            int readLength = 0;
            while ((readLength = sftp.read(sftpFileHandle, offset, buffer, 0, buffer.length)) != -1) {
                bos.write(buffer, 0, readLength);
                offset += readLength;
            }
            bos.flush();
        } catch (IOException ioe) {
            log.warn("取得失敗:" + ioe);
            return false;
        } finally {
            silentClose(bos);
            try {
                if (sftp != null) {sftp.closeFile(sftpFileHandle);}
            } catch (IOException ioe) {log.warn(remoteFileName + " close 失敗:" + ioe.toString());}
        }
        // ファイルサイズチェック
        File localFile = new File(localFileName);
        if (localFile.length() != remoteFileLength) {
            log.warn("サイズ不正: リモート:" + remoteFileLength + ", ローカル:" + localFile.length());
            localFile.delete();
            return false;
        }
        log.debug("取得: " + remoteFileLength + "byte : " + remoteFileName + " --> " +localFileName);
        return true;
    }


    /**
     * ローカルファイルを転送します。<br>
     * ローカルファイルは送信可能であること。<br>
     * 
     * @param sftp SFTPv3Client
     * @param remoteFileName リモートファイル名(パス含む)
     * @param localFileName ローカルファイル名(パス含む)
     */
    public static boolean put(final SFTPv3Client sftp, final String remoteFileName, final String localFileName) {
        // リモートファイルチェック
        try {
            SFTPv3FileAttributes attributes = sftp.stat(remoteFileName);
            if (attributes.isDirectory()) {
                log.warn("リモートファイル(" + remoteFileName + ")はディレクトリ");
                return false;
            }
            log.debug("リモートファイル(" + remoteFileName + ") " + "は存在します。上書きます。");
        } catch (IOException ioe) {
            if (ioe instanceof SFTPException) {
                SFTPException sftpe = (SFTPException) ioe;
                // SFTPException.ErrorCode == 2(No such file) is OK.
                if (sftpe.getServerErrorCode() != 2) {
                    log.warn("リモートファイル(" + remoteFileName + ") SFTPエラー:" + sftpe.toString());
                    return false;
                }
            } else {
                log.warn("リモートファイル(" + remoteFileName + ") 転送エラー:" + ioe.toString());
                return false;
            }
        }
        SFTPv3FileHandle sftpFileHandle = null;
        try {
            // create remote file
            sftpFileHandle = sftp.createFile(remoteFileName);
        } catch (IOException e) {
            log.warn("リモートファイル(" + remoteFileName + ") " + "作成エラー:" + e.toString());
            return false;
        }
        BufferedInputStream filein = null;
        try {
            // load local file.
            filein = new BufferedInputStream(new FileInputStream(localFileName));
            // Write bytes to a file. If len > 32768, then the write operation
            // will be split into multiple writes.
            byte[] buffer = new byte[1024];
            long offset = 0;
            int readLength = 0;
            while ((readLength = filein.read(buffer)) != -1) {
                sftp.write(sftpFileHandle, offset, buffer, 0, readLength);
                offset += readLength;
            }
        } catch (IOException ioe) {
            log.warn("送信失敗:" + ioe.toString());
            return false;
        } finally {
            silentClose(filein);
            try {
                if (sftp != null) {sftp.closeFile(sftpFileHandle);}
            } catch (IOException ioe) {
                log.warn(remoteFileName + " close error:" + ioe.toString());
            }
        }
        // compare size.
        try {
            long remoteFileLength = sftp.stat(remoteFileName).size.longValue();
            File localFile = new File(localFileName);
            if (remoteFileLength != localFile.length()) {
                sftp.rm(remoteFileName);
                log.warn("サイズ不正: リモート:" + remoteFileLength + ", ローカル:" + localFile.length());
                return false;
            }
        } catch (IOException ioe) {
            log.warn("転送エラー:" + ioe.toString());
            return false;
        }
        log.debug("送信:" + localFileName);
        return true;
    }

    /**
     * 接続を閉じます。<br>
     * IOExceptionが発生してもthrowしません。<br>
     * @param closeable
     */
    public static void silentClose(Closeable closeable) {
        try {
            if (closeable != null) {closeable.close();}
        } catch (IOException ioe) {log.warn("close error:" + ioe.toString());}
    }
}