package com.visystem.util;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.util.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* ftp连接工具类
* @author julong
* @date 2016-7-16 上午09:41:31
*/
public class FtpUtils{

/**
* 日志
* @author julong
* @date 2016-7-16 上午10:07:04
*/
private static final Logger logger = LoggerFactory.getLogger(FtpUtils.class);

/**
* ftp连接对象
* @author julong
* @date 2016-7-16 上午10:09:17
*/
public static FTPClient ftpClient = null;



/**
* byte[]转Base64String
* @param bytes
* @return String
* @author julong
* @date 2016-7-16 上午09:47:57
*/
public static String encodeBase64String(byte[] bytes){
logger.debug("【FtpUtil】byte[]转Base64String");
return Base64.encodeBase64String(bytes);
}

/**
* 解码-base64String 转byte[]
* @param base64String
* @return byte[]
* @author julong
* @date 2016-7-16 上午09:49:25
*/
public static byte[] decodeBase64String(String base64String){
logger.debug("【FtpUtil】base64String 转byte[]");
return Base64.decodeBase64(base64String);
}

/**
* 转码-byte[]转base64Byte[]
* @param binaryData
* @return
* @author julong
* @date 2016-7-16 上午09:53:30
*/
public static byte[] encodeBase64(byte[] binaryData){
logger.debug("【FtpUtil】byte[]转base64Byte[]");
return Base64.encodeBase64(binaryData);
}

/**
* 建立ftp连接对象
* @param hostname 主机IP
* @param port 端口
* @param username 登录名
* @param password 登录
* @return FTPClient
* @throws NumberFormatException
* @throws SocketException
* @throws IOException
* @author julong
* @date 2016-7-18 下午08:31:09
*/
public static FTPClient connection(String hostname, String port,String username, String password) throws NumberFormatException, SocketException, IOException{
logger.debug("【FtpUtil】-开始建立ftp连接对象");
ftpClient = new FTPClient();
//建立ftp连接
ftpClient.connect(hostname, Integer.valueOf(port));
ftpClient.login(username, password);
return ftpClient;
}
/**
* ftp是否已连接
* @return true/false
* @author julong
* @date 2016-7-16 上午10:15:01
*/
public static boolean isConnected(FTPClient ftpClient){
logger.debug("【FtpUtil】-ftp连接是否已经打开:{}",ftpClient.isConnected());
return ftpClient.isConnected();
}

/**
* 根据文件URL获取OutputStream
* @param remote 文件绝对URL
* @return OutputStream
* @throws IOException
* @author julong
* @date 2016-7-16 上午10:19:14
*/
public static OutputStream getFtpFileOutputStream(FTPClient ftpClient,String remote) throws IOException{
logger.debug("【FtpUtil】-根据文件URL获取OutputStream");
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);//设置以二进制传送
//ftpClient.enterLocalPassiveMode();//被动模式传送
return ftpClient.storeFileStream(remote);
}
/**
* 根据文件URL获取InputStream
* @param remote 文件绝对URL
* @return InputStream
* @throws IOException
* @author julong
* @date 2016-7-16 上午10:19:14
*/
public static InputStream getFtpFileInputStream(FTPClient ftpClient,String remote) throws IOException{
logger.debug("【FtpUtil】-根据文件URL获取InputStream");
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);//设置以二进制传送
//ftpClient.enterLocalPassiveMode();//被动模式传送
return ftpClient.retrieveFileStream(remote);
}

/**
* InputStream 转byte[]
* @param inputStream 输入流
* @return byte[]
* @throws IOException
* @author julong
* @date 2016-7-16 上午10:22:50
*/
public static byte[] getInputStreamToByte(InputStream inputStream) throws IOException{
logger.debug("【FtpUtil】-InputStream 转byte[]");
return IOUtils.toByteArray(inputStream);
}

/**
* 文件上传
* @param remote
* @param local
* @return
* @throws IOException
* @author julong
* @date 2016-7-20 下午01:35:40
*/
public static boolean storeFile(FTPClient ftpClient,String remote, InputStream local) throws IOException{
logger.debug("【FtpUtil】-InputStream 文件上传");
return ftpClient.storeFile(remote, local);
}



/**
* 关闭ftp
* @return boolean
* @throws IOException
* @author julong
* @date 2016-7-16 上午10:30:50
*/
public static boolean logout() throws IOException{
logger.debug("【FtpUtil】-关闭ftp");
return ftpClient.logout();
}
/**
* @return boolean
* @throws IOException
* @author julong
* @date 2016-7-16 上午10:30:50
*/
public static void disconnect() throws IOException{
logger.debug("【FtpUtil】-disconnect");
ftpClient.disconnect();
}

/**
* 关闭链接
* @throws IOException
* @author julong
* @date 2018年12月26日 下午12:05:17
* @desc
*/
public static void closeFtpClient() throws IOException{
logger.debug("【FtpUtil】-closeFtpClient");
if(ftpClient.isConnected()){
logger.debug("【FtpUtil】-关闭ftp链接服务");
ftpClient.logout();
ftpClient.disconnect();
}
}
/**
* 下载文件为BASE64字符串
* @param remote 文件路径
* @return String BASE64字符串
* @throws NumberFormatException
* @throws SocketException
* @throws IOException
* @author julong
* @date 2016-7-19 下午12:01:06
*/
public static String downloadFileToBase64(FTPClient ftpClient,String remote) throws NumberFormatException, SocketException, IOException{
InputStream inputStream = null;
String base64String = "";
boolean result = false;
try{
logger.debug("【FtpUtil】-文件下载downloadFileToBase64下载路径:{}",remote);
result = ftpClient.isConnected();
logger.debug("1.【FtpUtil】-建立ftp连接状态{}",result);
logger.debug("【FtpUtil】-{}",ftpClient.getReplyString());
if(!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){
return base64String;
}
if(result){
//开始下载
inputStream = FtpUtils.getFtpFileInputStream(ftpClient,remote);
if (null != inputStream) {
byte[] bytes = FtpUtils.getInputStreamToByte(inputStream);
base64String = FtpUtils.encodeBase64String(bytes);
}
logger.debug("【FtpUtil】-下载成功");
}
}finally{
if(null != inputStream){
inputStream.close();
}
}
return base64String;
}

/**
* 下载文件为二进制流
* @param remote 文件路径
* @return byte[]
* @throws NumberFormatException
* @throws SocketException
* @throws IOException
* @author julong
* @date 2016-7-19 下午12:01:43
*/
public static byte[] downloadFileToByte(FTPClient ftpClient,String remote) throws NumberFormatException, SocketException, IOException{
InputStream inputStream = null;
byte[] bytes = null;
boolean result = false;
try{
logger.debug("【FtpUtil】-文件下载downloadFileToByte");
result = FtpUtils.isConnected(ftpClient);
if(result){
//开始下载
inputStream = FtpUtils.getFtpFileInputStream(ftpClient,remote);
//转字符流
bytes = FtpUtils.getInputStreamToByte(inputStream);
}
}finally{
if(null != inputStream){
inputStream.close();
}
}
return bytes;
}
/**
* 根据文件路径上传文件文件上传操作
* @param pathname 文件路径
* @param remote 上传文件的路径
* @return boolean
* @throws IOException
* @author julong
* @date 2016-7-20 下午01:37:57
*/
public static boolean uploadFileToFtp(FTPClient ftpClient,String pathname,String remote) throws IOException{
boolean result = false;
boolean upload = false;
InputStream inputStream = null;
try {
logger.debug("【FtpUtil】-根据文件路径上传文件文件上传操作uploadFileToFtp");
result = FtpUtils.isConnected(ftpClient);
if(result){
File file = new File(pathname);
inputStream = new FileInputStream(file);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);//设置以二进制传送
//ftpClient.enterLocalPassiveMode();//被动模式传送
//开始上传
upload = ftpClient.storeFile(remote, inputStream);
logger.debug("【FtpUtil】-"+upload);
}
} finally{
if(null != inputStream){
inputStream.close();
}
}
return upload;
}
/**
* 根据文件Base64上传文件操作
* @param base64String Base64字符串
* @param remote 上传文件的路径(服务器路径)
* @return boolean
* @throws IOException
* @author julong
* @date 2016-7-20 下午01:37:57
*/
public static boolean uploadByteToFtp(FTPClient ftpClient,String base64String,String remote) throws IOException{
boolean result = false;
boolean upload = false;
InputStream inputStream = null;
logger.debug("【FtpUtil】-根据文件路径上传文件文件上传操作--开始{}",remote);
try {
result = ftpClient.isConnected();
logger.debug("1.【FtpUtil】-建立ftp连接状态{}",result);
logger.debug("【FtpUtil】-{}",ftpClient.getReplyString());
if(!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){
return false;
}
//判断ftp是否已连接
if(result){
//解码-base64String 转byte[]
byte[] bytes = FtpUtils.decodeBase64String(base64String);
inputStream = new ByteArrayInputStream(bytes);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);//设置以二进制传送
//ftpClient.enterLocalPassiveMode();//被动模式传送
//开始上传
upload = ftpClient.storeFile(remote, inputStream);
logger.debug("【FtpUtil】-上传文件结果:{}",upload);
}else{
logger.debug("2.【FtpUtil】-ftp连接失败");
}
} finally{
if(null != inputStream){
inputStream.close();
}
}
return upload;
}

/**
* 循环创建文件夹
* @param path
* @return
* @throws IOException
* @author julong
* @date 2018年12月1日 上午9:08:00
* @desc
*/
public static boolean createDirectories(FTPClient ftpClient,String path) throws IOException {
boolean result = false;
logger.debug("【FtpUtil】-ftp目录:{}",path);
if(ftpClient.isConnected()){
logger.debug("【FtpUtil】-{}",ftpClient.getReplyCode());
logger.debug("【FtpUtil】-{}",ftpClient.getReplyString());
//创建文件夹
if(StringUtils.isNotBlank(path)){
String[] pathArray = StringUtils.split(path,"/");
logger.debug("【FtpUtil】-当前需要文件夹数量是:{}",pathArray.length);
System.out.println("【FtpUtil】-当前需要文件夹数量是:{}"+pathArray.length);
for (String str : pathArray) {
result = ftpClient.changeWorkingDirectory(str);
logger.debug("【FtpUtil】-切换目录结果:{}",result);
System.out.println("【FtpUtil】-切换目录结果:{}"+result);
if(result == Boolean.FALSE){
result = ftpClient.makeDirectory(str);
logger.debug("【FtpUtil】-创建文件夹结果:{}",result);
System.out.println("【FtpUtil】-创建文件夹结果:{}"+result);
ftpClient.changeWorkingDirectory(str);
}
}
}
// ftpClient.changeWorkingDirectory("~");
}
return result;
}



/**
* @param args
* @author julong
* @date 2016-7-15 下午06:03:49
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
InputStream inputStream = null;
try {

System.out.println(System.getProperty("os.name"));
// FTPClient ftpClient = FtpUtils.connection("192.168.10.2", "21", "vicp", "vicp");
FTPClient ftpClient = FtpUtils.connection("192.168.10.132", "21", "vicp", "vicp");
System.out.println("当前ftp内存地址:"+ftpClient.getReplyString());
System.out.println(ftpClient.getSystemType());
boolean create = FtpUtils.createDirectories(ftpClient, "/aaaaa/bbbb/cccc/");
System.out.println("链接:"+create);

boolean upload = FtpUtils.uploadFileToFtp(ftpClient,"D:\\git.txt", "/home/vicp/aaaaa/bbbb/cccc/git01.txt");
System.out.println(upload);
boolean upload2 = FtpUtils.uploadFileToFtp(ftpClient,"D:\\git.txt", "/home/vicp/aaaaa/bbbb/cccc/git02.txt");
System.out.println(upload2);
boolean upload3 = FtpUtils.uploadFileToFtp(ftpClient,"D:\\git.txt", "/home/vicp/aaaaa/bbbb/cccc/git03.txt");
System.out.println(upload3);
boolean upload4 = FtpUtils.uploadFileToFtp(ftpClient,"D:\\git.txt", "/home/vicp/aaaaa/bbbb/cccc/git04.txt");
System.out.println(upload4);
if(ftpClient.isConnected()){
//【FtpUtil】-关闭ftp
ftpClient.logout();
ftpClient.disconnect();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(null != inputStream){
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

}