连接 sftp 并实时跟踪上传进度

1.导入sftpf的jar包 jsch-0.1.54.jar (jar版本太低会影响测试效果)

2.配置文件

host=192.168.132.138
username=root
password=root
privateKey=/home/webusr/.ssh
passphrase=id_rsa
port=22
local=/data/sftp/silver2KF/
movePath=/usr/local/src/test

3.上传主 SftpConfig 类

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.apache.log4j.Logger;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

public class SftpConfig {
	private Logger logger = Logger.getLogger(SftpConfig.class);
	private String host = null;// sftp服务器ip
	private String username = null;// 用户名
	private String password = null;// 密码
	private String privateKey = null;// 密钥文件路径
	private String passphrase = null;// 密钥口令
	private Integer port = null;// 默认的sftp端口号是22
	private String local = null;
	private String movePath = null;
	SftpMonitor monitor;
	private static ChannelSftp sftp = null;

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getPrivateKey() {
		return privateKey;
	}

	public void setPrivateKey(String privateKey) {
		this.privateKey = privateKey;
	}

	public String getPassphrase() {
		return passphrase;
	}

	public void setPassphrase(String passphrase) {
		this.passphrase = passphrase;
	}

	public Integer getPort() {
		return port;
	}

	public void setPort(Integer port) {
		this.port = port;
	}

	public String getLocal() {
		return local;
	}

	public void setLocal(String local) {
		this.local = local;
	}

	public String getMovePath() {
		return movePath;
	}

	public void setMovePath(String movePath) {
		this.movePath = movePath;
	}

	/**
	 * 初始化参数
	 */
	public SftpConfig() {
		Properties prop = new Properties();
		InputStream in = getClass().getResourceAsStream("/sftpConfig.properties");
		System.out.println("读取sftp配置文件");
		try {
			prop.load(in);
		} catch (IOException e) {
			logger.error("sftp properties file no has", e);
		}

		this.host = prop.getProperty("host");
		this.username = prop.getProperty("username");
		this.password = prop.getProperty("password");
		this.privateKey = prop.getProperty("privateKey");
		this.passphrase = prop.getProperty("passphrase");
		this.port = Integer.parseInt(prop.getProperty("port", ""));
		this.local = prop.getProperty("local");
		this.movePath = prop.getProperty("movePath");
		System.out.println("conn:" + getUsername() + "/" + getPassword() + "@"
				+ getHost() + "\n" + getLocal() + "[TO]" + getMovePath());

	}

	/**
	 * 连接sftp
	 * 
	 * @return
	 */
	public ChannelSftp getConnection() {
		System.out.println("连接sftp通道");
		JSch jSch = new JSch();
		Channel channel = null;
		try {
			Session session = jSch.getSession(username, host, port);// 根据用户名,主机ip,端口获取一个Session对象
			if (password != null && !"".equals(password)) {
				session.setPassword(password);// 设置密码
			}
			Properties config = new Properties();
			config.put("userauth.gssapi-with-mic", "no");// SSH连接慢的问题
			config.put("StrictHostKeyChecking", "no");// 防止远程主机公钥改变导致 SSH 连接失败
			session.setConfig(config); // 为Session对象设置properties
			session.setServerAliveInterval(92000);// 请求时长
			session.connect();// 通过session建立连接
			channel = session.openChannel("sftp"); // 指定连接sftp
			channel.connect();// 打开sftp的通道

		} catch (JSchException e) {
			e.printStackTrace();
		}
		sftp = (ChannelSftp) channel;
		return  sftp;
	}

	/**
	 * 文件上传
	 * 
	 * @param directory
	 *            上传的目录
	 * @param uploadFile
	 *            需要上传的文件
	 */
	public void upload(String directory, File uploadFile) {
		System.out.println("上传的目录:" + directory + ";上传的文件的路径:"
				+ uploadFile.getPath() + "; 文件名称 :" + uploadFile.getName());
		monitor = new SftpMonitor(uploadFile.length());
		try {
			sftp.cd(directory);
			sftp.put(new FileInputStream(uploadFile), uploadFile.getName(),
					monitor);
		} catch (Exception e) {
			e.printStackTrace();
			monitor.stop();
		}

	}

	/**
	 * 下载文件
	 * 
	 * @param directory
	 *            下载目录
	 * @param downloadFile
	 *            下载的文件
	 * @param saveFile
	 *            存在本地的路径
	 * @param sftp
	 */
	public void download(String directory, String downloadFile,
			String saveFile, ChannelSftp sftp) {
		try {
			sftp.cd(directory);
			sftp.get(downloadFile, saveFile);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e);
		}
	}

	/**
	 * 断开连接
	 * 
	 * @param sftp
	 * @throws JSchException
	 */
	public void disconnected() throws JSchException {
		if (sftp != null) {
			sftp.getSession().disconnect();
			sftp.disconnect();
		}
	}
	
}



4.实现接口SftpProgressMonitor, Runnable
SftpProgressMonitor:主要目的是获取开上传 与上传结束
Runnable:实时获取上传进度

import java.text.NumberFormat;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

import com.jcraft.jsch.SftpProgressMonitor;

public class SftpMonitor implements SftpProgressMonitor, Runnable {

	private long maxCount = 0;// 文件的总大小
	public long startTime = 0L;
	private long uploaded = 0;
	private boolean isScheduled = false;
	private Logger logger = Logger.getLogger(SftpMonitor.class);
	ScheduledExecutorService executorService;

	public SftpMonitor(long maxCount) {
		this.maxCount = maxCount;
	}

	@Override
	public void run() {
		NumberFormat format = NumberFormat.getPercentInstance();
		format.setMaximumFractionDigits(2);
		format.setMinimumFractionDigits(2);
		String value = format.format((uploaded / (double) maxCount));
		System.out.println("已传输:" + uploaded / 1024 + "KB,传输进度:" + value);
		if (uploaded == maxCount) {
			stop();
			long endTime = System.currentTimeMillis();
			System.out.println("传输完成!用时:" + (endTime - startTime) / 1000 + "s");
		}

	}

	/**
	 * 输出每个时间段的上传大小
	 */
	@Override
	public boolean count(long count) {
		if (!isScheduled) {
			createTread();
		}
		uploaded += count;
		// System.out.println("本次上传大小:" + count / 1024 + "KB,");
		if (count > 0) {
			return true;
		}
		return false;

	}

	/**
	 * 文件上传结束时调用
	 */
	@Override
	public void end() {
		// System.out.println("文件传输结束");
	}

	/**
	 * 文件上传时开始调用
	 */
	@Override
	public void init(int op, String src, String dest, long max) {
		System.out.println("开始上传文件:" + src + "至远程:" + dest + "文件总大小:" + maxCount
				/ 1024 + "KB");
		startTime = System.currentTimeMillis();
	}

	/**
	 * 创建一个线程每隔一定时间,输出一下上传进度
	 */
	public void createTread() {
		executorService = Executors.newSingleThreadScheduledExecutor();
		// 1秒钟后开始执行,每2杪钟执行一次
		executorService.scheduleWithFixedDelay(this, 1, 2, TimeUnit.SECONDS);
		isScheduled = true;
	}

	/**
	 * 停止方法
	 */
	public void stop() {
		boolean isShutdown = executorService.isShutdown();
		if (!isShutdown) {
			executorService.shutdown();
		}
	}

}



5.测试

import java.io.File;

public class TestSftp {

	
	public static void main(String[] args) {
		SftpConfig sftpConfig = new SftpConfig();
		sftpConfig.getConnection();
    	String uploadFile="C:/Users/bjp-yxkj-songwq/Pictures/Saved Pictures/詹姆斯.jpg";
    	File file = new File(uploadFile);
    	
		sftpConfig.upload(sftpConfig.getMovePath(), file);
		
	}
}



 

你可能感兴趣的:(连接 sftp 并实时跟踪上传进度)