1,建立Session,对应一个用户账户,并在无传输线程时自动关闭session
public class SFTPProcessor2 {
private static final Logger LOGGER = Logger.getLogger(SFTPProcessor2.class);
private static Session session = null;
public Session getConnect(Map serverMap) {
String ftpHost = serverMap.get(SFTPConstants.SFTP_SERVER_HOST);
String port = serverMap.get(SFTPConstants.SFTP_SERVER_PORT);
String ftpUserName = serverMap.get(SFTPConstants.SFTP_SERVER_USERNAME);
String ftpPassword = serverMap.get(SFTPConstants.SFTP_SERVER_PASSWORD);
// 默认的端口22 此处我是定义到常量类中;
int ftpPort = SFTPConstants.SFTP_DEFAULT_PORT;
// 判断端口号是否为空,如果不为空,则赋值
if (port != null && !port.equals("")) {
ftpPort = Integer.valueOf(port);
}
JSch jsch = new JSch(); // 创建JSch对象
// 按照用户名,主机ip,端口获取一个Session对象
try {
session = jsch.getSession(ftpUserName, ftpHost, ftpPort);
LOGGER.debug("Session created.");
if (ftpPassword != null) {
session.setPassword(ftpPassword); // 设置密码
}
// 具体config中需要配置那些内容,请参照sshd服务器的配置文件/etc/ssh/sshd_config的配置
Properties config = new Properties();
// 设置不用检查hostKey
// 如果设置成“yes”,ssh就会自动把计算机的密匙加入“$HOME/.ssh/known_hosts”文件,
// 并且一旦计算机的密匙发生了变化,就拒绝连接。
config.put("StrictHostKeyChecking", "no");
// UseDNS指定,sshd的是否应该看远程主机名,检查解析主机名的远程IP地址映射到相同的IP地址。
// 默认值是 “yes” 此处是由于我们SFTP服务器的DNS解析有问题,则把UseDNS设置为“no”
config.put("UseDNS", "no");
session.setConfig(config); // 为Session对象设置properties
session.setTimeout(SFTPConstants.SFTP_DEFAULT_TIMEOUT); // 设置timeout时候
session.connect(); // 经由过程Session建树链接
LOGGER.debug("Session connected.");
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return session;
}
/* public boolean upfile(InputStream is, OutputStream os) throws IOException{
boolean res = false;
byte[] b = new byte[1024*1024*100];
int read;
if(os!=null){
do {
read = is.read(b, 0, b.length);
if (read > 0) {
os.write(b, 0, read);
}
os.flush();
} while (read >= 0);
}
return res;
}*/
/* public void uploadFile(String localFile, String newName,
String remoteFoldPath) // throws AppBizException
{
InputStream input = null;
OutputStream os = null;
try {
File lf = new File(localFile);
input = new FileInputStream(lf);
// 改变当前路径到指定路径
channel.cd(remoteFoldPath);
long t1 = System.currentTimeMillis();
//channel.put(input, newName);
os = channel.put(newName
//, new ProgressMonitor(lf.length()) // 上传时不执行init()方法
,new ProgressMonitorByBytes(lf.length())
,ChannelSftp.OVERWRITE)
;
upfile(input,os);
channel.put(localFile
, newName
, new ProgressMonitorByBytes()
, ChannelSftp.OVERWRITE);
System.out.println("Time elapsed: " + (System.currentTimeMillis() - t1) + "(ms)");
} catch (Exception e) {
LOGGER.error("Upload file error", e);
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
}
}
}
}*/
public static void main(String[] args) throws Exception {
SFTPProcessor2 ftpUtil = new SFTPProcessor2();
Map ftpServerMap = new HashMap();
ftpServerMap.put((String) SFTPConstants.SFTP_SERVER_HOST, "localhost");
ftpServerMap.put((String) SFTPConstants.SFTP_SERVER_USERNAME, "name");
ftpServerMap.put((String) SFTPConstants.SFTP_SERVER_PASSWORD, "password");
ftpServerMap.put((String) SFTPConstants.SFTP_SERVER_PORT, "22");
ftpUtil.getConnect(ftpServerMap);
//ftpUtil.uploadFile("e:/eclipse-jee.zip", "eclipse-jee.zip", System.getProperty("file.separator"));
String rf1 = "eclipse-jee.zip";
String rp1 = System.getProperty("file.separator")+"d";
//String rp1 = "";
String rf2 = "zzzz.zip";
String rp2 = System.getProperty("file.separator")+"d";
//String rp2 = "";
String lf1 = "e:/yyyy.zip";
String lf2 = "e:/zzzz.zip" ;
DownLoadThread d1 = new DownLoadThread(session,rf1,rp1,lf1,
ftpServerMap.get((String) SFTPConstants.SFTP_SERVER_HOST),
ftpServerMap.get((String) SFTPConstants.SFTP_SERVER_USERNAME),
"TRANS100");
DownLoadThread d2 = new DownLoadThread(session,rf2,rp2,lf2,
ftpServerMap.get((String) SFTPConstants.SFTP_SERVER_HOST),
ftpServerMap.get((String) SFTPConstants.SFTP_SERVER_USERNAME),
"TRANS99");
final Thread t1 = new Thread(d1);
final Thread t2 = new Thread(d2);
t1.start();
t2.start();
final List lst = new ArrayList();
lst.add(t1);
lst.add(t2);
//ftpUtil.downloadFile("eclipse-jee.zip", System.getProperty("file.separator")+"d", "e:/zzzz.zip");
//ftpUtil.downloadFile("snagit.zip", System.getProperty("file.separator")+"d", "e:/test20150608.zip");
Thread t3 = new Thread(new Runnable(){
@Override
public void run() {
while(true){
boolean nonlive = true;
for (int i = 0; i < lst.size(); i++) {
if(lst.get(i).isAlive()){
nonlive = false;
break;
}
}
if( nonlive ){
System.out.println("No Active transmission, exit!");
session.disconnect();
break;
}
}
}
});
//t3.setDaemon(true);
t3.start();
}
}
public class DownLoadThread implements Runnable {
private static final Logger LOGGER = Logger.getLogger(SFTPProcessor2.class);
private ChannelSftp channel = null;
private Session session = null;
private ProgressMonitorByBytes monitor = null;
private String remotef = null;
private String remotep = null;
private String lf = null;
private String ftpuser = null;
private String ftphost = null;
private String transid = null;
public DownLoadThread(Session ss , String rf ,String rp, String lf ,String host, String user,String tid) {
this.session = ss;
//this.monitor = p;
this.remotef = rf;
this.remotep = rp;
this.lf = lf;
this.ftphost = host;
this.ftpuser = user;
this.transid = tid;
}
@Override
public void run() {
try {
channel = getOpenCh(session,ftphost,ftpuser);
monitor = new ProgressMonitorByBytes(transid,remotef,this.getRemoteFilesize1(channel,remotef,remotep));
downloadFile(this.remotef,this.remotep,this.lf);
closeChannel();
//Thread.currentThread().interrupt();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public ChannelSftp getOpenCh(Session ss ,String ftphost,String ftpusername){
try {
LOGGER.debug("Opening SFTP Channel.");
channel = (ChannelSftp) ss.openChannel("sftp"); // 打开SFTP通道
channel.connect(); // 建树SFTP通道的连接
LOGGER.debug("Connected successfully to ftpHost = " + ftphost
+ ",as ftpUserName = " + ftpusername + ", returning: "
+ channel);
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return channel;
}
public void closeChannel()
{
try {
if (channel != null) {
channel.disconnect();
}
} catch (Exception e) {
LOGGER.error("close sftp error", e);
// throw new AppBizException(AppExcCodes.CLOSE_FTP_ERROR,
// "close ftp error.");
}
}
public void downloadFile(String remoteFile, String remotePath,String localFile) {
OutputStream output = null;
File file = null;
try {
file = new File(localFile);
if (!checkFileExist(localFile)) {
file.createNewFile();
output = new FileOutputStream(file);
channel.cd(remotePath);
//channel.get(remoteFile, output);
channel.get(remoteFile, localFile
//, new ProgressMonitor(getRemoteFilesize1(channel,remoteFile,remotePath))
,monitor
, ChannelSftp.OVERWRITE);
}else{
//output = new FileOutputStream(file);
channel.cd(remotePath);
channel.get(remoteFile, localFile
//, new ProgressMonitor(getRemoteFilesize1(channel,remoteFile,remotePath))
,monitor
, ChannelSftp.RESUME);
}
} catch (Exception e) {
LOGGER.error("Download file error", e);
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
}
}
if (file != null) {
//file.delete();
}
}
}
private boolean checkFileExist(String localPath) {
File file = new File(localPath);
return file.exists();
}
public long getRemoteFilesize1(ChannelSftp cf , String remoteFile,String remotepath ) {
Object o = null;
long s = 0;
try {
Vector v = cf.ls(cf.pwd() + "/" + remotepath + "/" + remoteFile);
if(v!=null && v.size() == 1){
o = v.firstElement();
}
//System.out.println();
LsEntry cl = (LsEntry)o;
s = cl.getAttrs().getSize();
System.out.println(s + "(bytes)");
} catch (SftpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return s;
}
}
public class ProgressMonitorByBytes implements SftpProgressMonitor {
private long transfered;
private long filesize;
private String remotef;
private Formatter f = null;
private long stime;
private long etime;
private String transferID ;
public ProgressMonitorByBytes(String transid,String remotefile,
long totalsize
) {
this.filesize = totalsize;
this.remotef = remotefile;
this.transferID = transid ;
}
public void sendmsg(){
DecimalFormat df = new DecimalFormat( "#.##");
String per = df.format(100*(1.0f*transfered/filesize));
System.out.println("Currently transferred total size: " + transfered + " bytes, percent: " + per + "% [" + remotef + "]" );
f.format("%1$10s\n","Currently transferred total size: " + transfered + " bytes, percent: " + per + "% [" + remotef + "] " );
}
@Override
public boolean count(long count) {
long now = System.currentTimeMillis();
long timeelapse = (now - stime);
boolean cancelCondition = (timeelapse > 10*1000) && "TRANS1000".equals(transferID);
if(transfered != filesize ) {
sendmsg();
transfered = transfered + count;
if(cancelCondition){ //作为取消下载使用,可以取消(暂停下载)
f.format("%1$10s\n","Cancel transfer: [" + remotef + "]");
System.out.printf("%1$10s\n","Cancel transfer: [" + remotef + "]");
return false;
}
boolean sleepCondition = (1000 * (1.0d/1024) * transfered / timeelapse ) > 4096 ;
if(sleepCondition){
try {
Thread.currentThread().sleep(1000); //作为限速使用,貌似可以限制下载速度
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return true;
}
return false;
}
@Override
public void end() {
etime = System.currentTimeMillis();
sendmsg();
System.out.println("Transferring done. [" + remotef + "]");
f.format("%1$10s\n", "Transferring done. [" + remotef + "]");
f.format("%1$10s\n", "Time Elapsed:"+ getTimePassed(etime - stime) +" [" + remotef + "]");
f.close();
}
public String getTimePassed(long times){
String res = "";
long hours = 0;
long minutes = 0 ;
long seconds = 0 ;
long millseconds = 0;
hours = times / (1000*60*60);
minutes = (times - hours * (1000*60*60)) / (1000*60);
seconds = (times - hours * (1000*60*60) - minutes*1000*60) / 1000;
millseconds = times - hours * (1000*60*60) - minutes*1000*60 - seconds*1000;
res = Long.toString(hours, 10)+"小时" + Long.toString(minutes, 10)+"分钟"+ Long.toString(seconds, 10)+"秒"+ Long.toString(millseconds, 10)+"毫秒";
return res;
}
/**
* @param arg0 1:下载,0:上传
* @param arg1 原始文件PATH
* @param arg2 目标文件PATH
* @param arg3 文件大小
*
* */
@Override
public void init(int arg0, String arg1, String arg2, long arg3) {
stime = System.currentTimeMillis();
try {
f = new Formatter(new FileOutputStream("E:/xdownlog.log", true));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
f.format("%1$10s\n", "Transferring begin. [" + remotef + "]");
//filesize = arg3;
System.out.println("Transferring begin. [" + remotef + "]");
System.out.println("======================");
System.out.println(arg0);System.out.println(arg1);System.out.println(arg2);System.out.println(arg3);
System.out.println("======================");
}
}
public class SFTPConstants {
public static final int SFTP_DEFAULT_TIMEOUT = 0;
public static final Object SFTP_SERVER_HOST = "SFTP_SERVER_HOST";
public static final Object SFTP_SERVER_PORT = "SFTP_SERVER_PORT";
public static final Object SFTP_SERVER_USERNAME = "SFTP_SERVER_USERNAME";
public static final Object SFTP_SERVER_PASSWORD = "SFTP_SERVER_PASSWORD";
public static final int SFTP_DEFAULT_PORT = 22;
}