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());} } }