package cn.com.sparknet.fileStoreLiunx;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;
//LIUNX系统需要安装FTP服务
public class Ftp {
//打印log日志
private static final Log logger = LogFactory.getLog(Ftp.class);
private static Date last_push_date = null;
private Session sshSession;
private ChannelSftp channel;
private static ThreadLocal<Ftp> sftpLocal = new ThreadLocal<Ftp>();
private Ftp(String host, int port, String username, String password){
try{
JSch jsch = new JSch();
jsch.getSession(username, host, port);
//根据用户名,密码,端口号获取session
sshSession = jsch.getSession(username, host, port);
sshSession.setPassword(password);
//修改服务器/etc/ssh/sshd_config 中 GSSAPIAuthentication的值yes为no,解决用户不能远程登录
sshSession.setConfig("userauth.gssapi-with-mic", "no");
//为session对象设置properties,第一次访问服务器时不用输入yes
sshSession.setConfig("StrictHostKeyChecking", "no");
sshSession.connect();
//获取sftp通道
channel = (ChannelSftp)sshSession.openChannel("sftp");
channel.connect();
logger.info("连接ftp成功!" + sshSession);
}catch (Exception e) {
// TODO: handle exception
}
}
/**
* 是否已连接
*
* @return
*/
private boolean isConnected() {
return null != channel && channel.isConnected();
}
/**
* 载单个文件
* @param directory :远程下载目录(以路径符号结束) 如:/home/sftp/jiesuan_2/2014/
* @param remoteFileName FTP服务器文件名称 如:xxx.txt ||xxx.txt.zip
* @param localFile 本地文件路径 如 D:\\xxx.txt
* @return
* @throws GoPayException
*/
public void downloadFile(String directory, String remoteFileName,String localFile) throws Exception {
File file = null;
OutputStream output = null;
try {
file = new File(localFile);
if (file.exists()){
file.delete();
}
file.createNewFile();
channel.cd(directory);
output = new FileOutputStream(file);
channel.get(remoteFileName, output);
}
catch (SftpException e) {
System.out.println("文件不存在或ftp目录或者文件异常,检查ftp目录和文件");
}
catch (FileNotFoundException e) {
System.out.println("本地目录异常,请检查");
}
catch (IOException e) {
System.out.println("创建本地文件失败");
}
finally {
if (output != null) {
try {
output.close();
}
catch (IOException e) {
System.out.println("关闭流失败");
}
}
}
System.out.println("ftp下载文件结束");
}
/**
* 获取本地线程存储的sftp客户端
*
* @return
* @throws Exception
*/
public static Ftp getSftpUtil(String host, int port, String username, String password) throws Exception {
//获取本地线程
Ftp sftpUtil = sftpLocal.get();
if (null == sftpUtil || !sftpUtil.isConnected()) {
//将新连接防止本地线程,实现并发处理
sftpLocal.set(new Ftp(host, port, username, password));
}
return sftpLocal.get();
}
/**
* 释放本地线程存储的sftp客户端
*/
public static void release() {
if (null != sftpLocal.get()) {
sftpLocal.get().closeChannel();
logger.info("关闭连接" + sftpLocal.get().sshSession);
sftpLocal.set(null);
}
}
/**
* 关闭通道
*
* @throws Exception
*/
public void closeChannel() {
if (null != channel) {
try {
channel.disconnect();
} catch (Exception e) {
logger.error("关闭SFTP通道发生异常:", e);
}
}
if (null != sshSession) {
try {
sshSession.disconnect();
} catch (Exception e) {
logger.error("SFTP关闭 session异常:", e);
}
}
}
/**
* @param directory 上传ftp的目录
* @param uploadFile 本地文件目录
*
*/
public void upload(String directory, File file) throws Exception {
createDir(directory,channel);
InputStream input = new BufferedInputStream(new FileInputStream(file));
channel.put(input, file.getName());
if (input != null) {
input.close();
}
System.out.println("文件上传成功");
}
//获取文件
public List<File> getFiles(String realpath, List<File> files) {
File realFile = new File(realpath);
if (realFile.isDirectory()) {
File[] subfiles = realFile.listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
if (null == last_push_date ) {
return true;
} else {
long modifyDate = file.lastModified();
return modifyDate > last_push_date.getTime();
}
}
});
for (File file : subfiles) {
if (file.isDirectory()) {
getFiles(file.getAbsolutePath(), files);
} else {
files.add(file);
}
if (null == last_push_date) {
last_push_date = new Date(file.lastModified());
} else {
long modifyDate = file.lastModified();
if (modifyDate > last_push_date.getTime()) {
last_push_date = new Date(modifyDate);
}
}
}
}
return files;
}
/**
* 创建一个文件目录
* @throws Exception
*/
public static void createDir(String createpath, ChannelSftp sftp) {
try {
if (isDirExist(createpath, sftp)) {
sftp.cd(createpath);
return;
}
String pathArry[] = createpath.split("/");
StringBuffer filePath = new StringBuffer("/");
for (String path : pathArry) {
if (path.equals("")) {
continue;
}
filePath.append(path + "/");
if (isDirExist(filePath.toString(), sftp)) {
sftp.cd(filePath.toString());
} else {
// 建立目录
sftp.mkdir(filePath.toString());
// 进入并设置为当前目录
sftp.cd(filePath.toString());
}
}
sftp.cd(createpath);
} catch (Exception e) {
System.out.println("创建路径错误:");
}
}
/**
* 判断目录是否存在
*/
public static boolean isDirExist(String directory,ChannelSftp sftp) {
boolean isDirExistFlag = false;
try {
SftpATTRS sftpATTRS = sftp.lstat(directory);
isDirExistFlag = true;
return sftpATTRS.isDir();
} catch (Exception e) {
if (e.getMessage().toLowerCase().equals("no such file")) {
isDirExistFlag = false;
}
}
return isDirExistFlag;
}
public static void main(String[] args) {
try {
Ftp ftp=getSftpUtil("192.168.1.137", 22, "root", "root123.");
File file = new File("D:/登记模板.doc");
ftp.upload("/home/jihu",file);
ftp.downloadFile("/home/jihu/","登记模板.doc","E:/登记模板2.doc");
release();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}