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 {
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
@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;
}
SFTPv3FileHandle sftpFileHandle = null;
try {
sftpFileHandle = sftp.openFileRO(remoteFileName);
} catch (IOException ioe) {
log.warn("リモートファイル(" + remoteFileName + ") open error:" + ioe);
return false;
}
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(new FileOutputStream(localFileName));
byte[] buffer = new byte[1024 * 8];
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
@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;
if (sftpe.getServerErrorCode() != 2) {
log.warn("リモートファイル(" + remoteFileName + ") SFTPエラー:" + sftpe.toString());
return false;
}
} else {
log.warn("リモートファイル(" + remoteFileName + ") 転送エラー:" + ioe.toString());
return false;
}
}
SFTPv3FileHandle sftpFileHandle = null;
try {
sftpFileHandle = sftp.createFile(remoteFileName);
} catch (IOException e) {
log.warn("リモートファイル(" + remoteFileName + ") " + "作成エラー:" + e.toString());
return false;
}
BufferedInputStream filein = null;
try {
filein = new BufferedInputStream(new FileInputStream(localFileName));
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());
}
}
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());}
}
}