package cn.sccl.common;
import java.io.File;
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.io.UnsupportedEncodingException;
import java.net.SocketException;
import java.nio.charset.Charset;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.servlet.ServletOutputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.eclipse.jetty.util.log.Log;
import org.springframework.http.MediaType;
import com.alibaba.druid.util.StringUtils;
import net.sf.json.JSONObject;
/**
* 20190319
* @author 郑生伟
*/
public class FTPUtils {
private static Logger logger = Logger.getLogger(FTPUtils.class);
private static String ipAddress=SysPropUtils.getProperty("ftpIp");
private static int port=Integer.parseInt(SysPropUtils.getProperty("ftpPort"));
private static String ftpName=SysPropUtils.getProperty("ftpUserName");
private static String ftpPassword=SysPropUtils.getProperty("ftpPassword");
private static String ftpBasePath=SysPropUtils.getProperty("ftpBasePath");
private static FTPClient ftpClient;
private static final String FILE_SEPERATOR=File.separator;
//timeout10
private static final int TIME_OUT=Integer.parseInt(SysPropUtils.getPropertyDefaultVaue("ftpTimeOut","10000"));
private static String uploadType=SysPropUtils.getPropertyDefaultVaue("uploadType","ftp");
public static final String DEFAULT_CHARACTOR_SET="UTF-8";
public FTPUtils(String ipAddress,int port,String ftpName,String ftpPassword){
FTPUtils.ipAddress=ipAddress;
FTPUtils.port=port;
FTPUtils.ftpName=ftpName;
FTPUtils.ftpPassword=ftpPassword;
}
private static boolean login() throws SocketException, IOException{
ftpClient=new FTPClient();
ftpClient.setConnectTimeout(TIME_OUT);
ftpClient.connect(ipAddress, port);
ftpClient.enterLocalPassiveMode();//被动模式 只要服务端端口对客户端开发即可
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
boolean isLogined=ftpClient.login(ftpName, ftpPassword);
return isLogined;
}
/**
*
* @param in
* @param uploadPath
* @param fileName
* @param charSet
* @return
* @throws Exception
* @throws IOException
*/
public static boolean uploadFile(InputStream in,String uploadPath,String fileName,String charSet) throws IOException, Exception{
if(uploadType.equals("ftp")){
return uplodFileByFtp(in, uploadPath, fileName, charSet);
}else if(uploadType.equals("http")){
return uploadFileByHttp(in,uploadPath,fileName,null);
}else{
return false;
}
}
public static boolean uploadFileByHttp(InputStream in, String uploadPath, String fileName,JSONObject jsonResult) throws Exception, IOException {
HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(SysPropUtils.FILE_UPLOAD_URL);
MultipartEntityBuilder mf = MultipartEntityBuilder.create();
mf.addBinaryBody("file",in,ContentType.MULTIPART_FORM_DATA,fileName);
mf.setCharset(Charset.forName("utf-8"));
mf.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
if(uploadPath!=null){
StringBody stringBody=new StringBody(uploadPath,ContentType.MULTIPART_FORM_DATA);
mf.addPart("pathName", stringBody);
}
post.setEntity(mf.build());
HttpResponse res = client.execute(post);
HttpEntity entity = res.getEntity();
String result = EntityUtils.toString(entity,"UTF-8");
JSONObject json=JSONObject.fromObject(result);
String code=json.get("code").toString();
logger.info(result);
if("200".equals(code)){
if(jsonResult!=null){
jsonResult.put("url", json.get("url"));
}
return true;
}
return false;
}
private static boolean uplodFileByFtp(InputStream in, String uploadPath, String fileName, String charSet) {
Boolean uploadFlag=true;
try {
boolean isLogin=login();
if(StringUtils.isEmpty(charSet))
charSet=DEFAULT_CHARACTOR_SET;
ftpClient.setControlEncoding(charSet);
if(isLogin){
logger.info(ftpName+":登录成功");
uploadFlag=createUploadPath(uploadPath);
}else{
uploadFlag=isLogin;
}
if(uploadFlag!=null){
//准备就绪上传文件
logger.info("开始上传文件...."+fileName);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
uploadFlag=ftpClient.storeFile(encodeName(fileName), in);
}else{
uploadFlag=false;
}
} catch (Exception e) {
e.printStackTrace();
logger.error("上传文件出错",e);
uploadFlag=false;
}finally{
disConnect();
if(in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return uploadFlag;
}
public static boolean deleteFile(String pathName,String fileName) throws Exception{
if("ftp".equals(uploadType)){
return deleteFileByFtp(pathName, fileName);
}else if("http".equals(uploadType)){
return deleteFileByHttp(pathName, fileName);
}else{
return false;
}
}
private static boolean deleteFileByHttp(String pathName, String fileName) throws Exception {
HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(SysPropUtils.FILE_DELETE_URL);
List<NameValuePair> list = new LinkedList<>();
BasicNameValuePair param1 = new BasicNameValuePair("pathName", pathName);
BasicNameValuePair param2 = new BasicNameValuePair("ftpFileName", fileName);
list.add(param1);
list.add(param2);
// 使用URL实体转换工具
UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(list, "UTF-8");
post.setEntity(entityParam);
HttpResponse response=client.execute(post);
// 获得响应的实体对象
HttpEntity entity = response.getEntity();
// 使用Apache提供的工具类进行转换成字符串
String entityStr = EntityUtils.toString(entity, "UTF-8");
JSONObject json=JSONObject.fromObject(entityStr);
if(json.getString("code").equals("0")){
logger.warn("删除失败=="+entityStr);
return false;
}
return true;
}
private static boolean deleteFileByFtp(String pathName, String fileName) {
boolean isDelete=true;
try {
login();
ftpClient.changeWorkingDirectory(getPathName(pathName));
ftpClient.dele(fileName);
} catch (Exception e) {
logger.error("删除文件出错",e);
}finally{
disConnect();
}
return isDelete;
}
private static String getPathName(String pathName) {
return pathName.startsWith(FILE_SEPERATOR)?pathName.substring(pathName.indexOf(FILE_SEPERATOR)+1):pathName;
}
//中文修改字符集 否则上传失败
private static String encodeName(String fileName){
try {//ftp默认传输字符为iso-8859-1所以中文名称需要更改
return new String(fileName.getBytes("GBK"),"iso-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
private static String decodeName(String fileName){
try {
return new String(fileName.getBytes("iso-8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
public static boolean downloadFile(OutputStream out,String pathName,final String fileName,String charSet){
if("ftp".equals(uploadType)){
return downloadFileByFtp(out, pathName, fileName, charSet);
}else if("http".equals(uploadType)){
return downloadFileByHttp(out,pathName,fileName,charSet);
}else{
Log.warn(uploadType+"不合法");
return false;
}
}
public static InputStream getInputStream(String fileName,String pathName,String charSet){
try {
if("ftp".equals(uploadType)){
return getInputStreamByFtp(fileName, pathName, charSet);
}else if("http".equals(uploadType)){
return getInputStreamByHttp(fileName, pathName, charSet);
}else{
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static InputStream getInputStreamByHttp(String fileName, String pathName, String charSet) throws Exception {
HttpClient client=HttpClientBuilder.create().build();
HttpPost post=new HttpPost(SysPropUtils.FILE_GET_URL);
List<NameValuePair> list = new LinkedList<>();
BasicNameValuePair param1 = new BasicNameValuePair("pathName", pathName);
BasicNameValuePair param2 = new BasicNameValuePair("ftpFileName", fileName);
list.add(param1);
list.add(param2);
UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(list,charSet);
post.setEntity(entityParam);
HttpResponse response=client.execute(post);
HttpEntity entity=response.getEntity();
/*if(!MediaType.MULTIPART_FORM_DATA_VALUE.equals(entity.getContentType().getValue())){
logger.warn("下载出错。。响应类型:"+entity.getContentType());
return null;
}*/
InputStream in=entity.getContent();
return in;
}
private static InputStream getInputStreamByFtp(String fileName, String pathName, String charSet) {
InputStream in=null;
boolean isLogin=true;
try {
isLogin=login();
String fullPath=getPathName(pathName);
if(isLogin){
logger.info("登录成功..getInputStream");
if(StringUtils.isEmpty(charSet))
charSet=DEFAULT_CHARACTOR_SET;
ftpClient.setControlEncoding(charSet);
ftpClient.changeWorkingDirectory(fullPath);
in=ftpClient.retrieveFileStream(encodeName(fileName));
}
} catch (Exception e) {
e.printStackTrace();
}
return in;
}
public static boolean downloadFileByHttp(OutputStream out, String pathName, String fileName, String charSet) {
// 使用URL实体转换工具
InputStream in=null;
try {
in=getInputStreamByHttp(fileName, pathName, charSet);
byte[] bytes=new byte[8192];
int index=0;
while((index=in.read(bytes))!=-1){
out.write(bytes, 0, index);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}finally{
try {
if(in!=null){
in.close();
}
if(out!=null&&!(out instanceof ZipOutputStream)){
out.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return true;
}
private static boolean downloadFileByFtp(OutputStream out, String pathName, final String fileName, String charSet) {
boolean isDownload=true;
try {
isDownload=login();
String fullPath=getPathName(pathName);
if(isDownload){
logger.info("登录成功..getInputStream"+pathName);
if(StringUtils.isEmpty(charSet))
charSet=DEFAULT_CHARACTOR_SET;
ftpClient.setControlEncoding(charSet);
/*ftpClient.changeWorkingDirectory(fullPath);*/
ftpClient.changeWorkingDirectory(fullPath);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
boolean flag=ftpClient.retrieveFile(encodeName(fileName), out);
logger.info("下载成功..getInputStream"+pathName+"成功了吗?"+(flag?"是的":"没有成功"));
}
} catch (Exception e) {
e.printStackTrace();
logger.error("下载出错",e);
}finally{
disConnect();
if(out!=null&&!(out instanceof ZipOutputStream)){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
private static void disConnect(){
if (ftpClient != null && ftpClient.isConnected()) {
try {
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException e) {
logger.error("关闭ftp失败{"+e.getMessage()+"}");
}
}
}
private static boolean isExitsDir(String pathName) throws IOException{
return ftpClient.changeWorkingDirectory(pathName);
}
private static Boolean createUploadPath(String pathName){
Boolean isCreate;
try {
isCreate = isExitsDir(getPathName(pathName));
if(!isCreate){
pathName=pathName.replace(FILE_SEPERATOR, ",");
String[] paths=pathName.split(",");
String basePath=ftpBasePath;
for(String path:paths){
basePath+=FILE_SEPERATOR+path;
if(!isExitsDir(path)){
if(!ftpClient.makeDirectory(path)){
return null;
}else{
isCreate=true;
isCreate=ftpClient.changeWorkingDirectory(path);
}
}
}
}
} catch (IOException e) {
logger.error("切到上传目录出错", e);
isCreate=null;
}
return isCreate;
}
public static void main(String[] args) throws FileNotFoundException {
/*boolean flag=uploadFile(new FileInputStream(new File("C:\\offline_FtnInfo.txt")),"test1\\test","你好.txt",null);*/
/*deleteFile("test1\\test2", "test1.txt");*
downloadFile(new FileOutputStream("D:\\1234.txt"), "test1\\test", "你好.txt", "UTF-8");*/
try {
deleteFile("test1\\test", "你好4.txt");
boolean flag=uploadFile(new FileInputStream(new File("C:\\offline_FtnInfo.txt")),"test1\\test","你好4.txt",null);
/*downloadFile(new FileOutputStream("D:\\xixiix1.txt"), "test1\\test", "你好4.txt", "UTF-8");*/
/*deleteFile("test1\\test", "你好4.txt");*/
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void batchDownloadFile(OutputStream outputStream, String pathName, List<UploadFile> uploadFiles,
String charSet) {
ZipOutputStream zos=null;
try{
if(StringUtils.isEmpty(charSet)){
charSet=DEFAULT_CHARACTOR_SET;
}
zos=new ZipOutputStream(outputStream);
if(uploadType.equalsIgnoreCase("ftp")){
batchDownLoadByFtp(zos,pathName,uploadFiles,charSet);
}else if(uploadType.equalsIgnoreCase("http")){
batchDownLoadByHttp(zos,pathName,uploadFiles,charSet);
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(zos!=null){
try {
zos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
private static void batchDownLoadByFtp(ZipOutputStream zos, String pathName, List<UploadFile> uploadFiles,
String charSet) {
boolean isDownload=true;
try {
isDownload=login();
String fullPath=getPathName(pathName);
if(isDownload){
logger.info("登录成功..getInputStream"+pathName);
if(StringUtils.isEmpty(charSet))
charSet=DEFAULT_CHARACTOR_SET;
ftpClient.setControlEncoding(charSet);
ftpClient.changeWorkingDirectory(fullPath);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
for(UploadFile uploadFile:uploadFiles){
ZipEntry zipEntry=new ZipEntry(uploadFile.getFileName());
zos.putNextEntry(zipEntry);
ftpClient.retrieveFile(encodeName(uploadFile.getFileId()), zos);
}
logger.info("下载成功..getInputStream"+pathName);
}
} catch (Exception e) {
e.printStackTrace();
logger.error("下载出错",e);
}finally{
disConnect();
}
}
private static void batchDownLoadByHttp(ZipOutputStream zos, String pathName, List<UploadFile> uploadFiles,
String charSet) throws IOException {
for(UploadFile uploadFile:uploadFiles){
ZipEntry zipEntry=new ZipEntry(uploadFile.getFileName());
zos.putNextEntry(zipEntry);
downloadFileByHttp(zos, pathName, uploadFile.getFileId(), charSet);
}
}
}