package com.vcredit.ddcash.server.commons.net;
import com.vcredit.ddcash.server.commons.model.FtpParam;
import org.apache.commons.net.ftp.*;
import org.apache.commons.net.ftp.parser.MLSxEntryParser;
import org.apache.commons.net.io.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
/**
* Created by guanshuli on 2017/2/7.
*/
public class FTPClient extends org.apache.commons.net.ftp.FTPClient {
private static final Logger logger = LoggerFactory.getLogger(FTPClient.class);
public String __systemName;
public boolean __autodetectEncoding = false;
public int __dataConnectionMode;
public int __fileType;
public boolean __remoteVerificationEnabled;
public int __controlKeepAliveReplyTimeout = 1000;
public long __controlKeepAliveTimeout;
public int __fileFormat;
public int __bufferSize;
public CopyStreamListener __copyStreamListener;
public int receiveBufferSize = -1;
public int sendBufferSize = -1;
static String __parsePathname(String reply) {
String param = reply.substring(4);
if (param.startsWith(""")) {
StringBuilder sb = new StringBuilder();
boolean quoteSeen = false;
for (int i = 1; i < param.length(); ++i) {
char ch = param.charAt(i);
if (ch == 34) {
if (quoteSeen) {
sb.append(ch);
quoteSeen = false;
} else {
quoteSeen = true;
}
} else {
if (quoteSeen) {
return sb.toString();
}
sb.append(ch);
}
}
if (quoteSeen) {
return sb.toString();
}
}
return param;
}
public void closeFtpClient() throws IOException {
this.logout();
if (this.isAvailable()) {
this.disconnect();
}
}
public boolean exists(String pathname) throws IOException {
return this.listNames(pathname).length > 0;
}
public boolean existsDir(String fileName) throws IOException {
return this.listDirectories(fileName).length >0;
}
public boolean isFile(String fileName) throws IOException {
return this.listFiles(fileName)[0].isFile();
}
public FTPFile getFile(String fileName) throws IOException {
return this.listFiles(fileName)[0];
}
public void connect(InetAddress host, int port) throws IOException {
this._socket_ = this._socketFactory_.createSocket();
if (this.receiveBufferSize != -1) {
this._socket_.setReceiveBufferSize(this.receiveBufferSize);
}
if (this.sendBufferSize != -1) {
this._socket_.setSendBufferSize(this.sendBufferSize);
}
this._socket_.connect(new InetSocketAddress(host, port), this.connectTimeout);
this._connectAction_();
}
private boolean __storeFile(FTPCmd command, String remote, InputStream local) throws IOException {
return this._storeFile(command.getCommand(), remote, local);
}
protected boolean _storeFile(String command, String remote, InputStream local) throws IOException {
Socket socket = this._openDataConnection_(command, remote);
if (socket == null) {
return false;
} else {
Object output = this.getBufferedOutputStream(socket.getOutputStream());
if (this.__fileType == 0) {
output = new ToNetASCIIOutputStream((OutputStream) output);
}
CSL csl = null;
if (this.__controlKeepAliveTimeout > 0L) {
csl = new CSL(this, this.__controlKeepAliveTimeout, this.__controlKeepAliveReplyTimeout);
}
this.setBufferSize(8*1024);
try {
Util.copyStream(local, (OutputStream) output, this.getBufferSize(), -1L, this.__mergeListeners(csl), true);
} catch (IOException var8) {
Util.closeQuietly(socket);
if (csl != null) {
csl.cleanUp();
}
throw var8;
}
((OutputStream) output).close();
socket.close();
if (csl != null) {
csl.cleanUp();
}
return this.completePendingCommand();
}
}
private CopyStreamListener __mergeListeners(CopyStreamListener local) {
if (local == null) {
return this.__copyStreamListener;
} else if (this.__copyStreamListener == null) {
return local;
} else {
CopyStreamAdapter merged = new CopyStreamAdapter();
merged.addCopyStreamListener(local);
merged.addCopyStreamListener(this.__copyStreamListener);
return merged;
}
}
private OutputStream __storeFileStream(FTPCmd command, String remote) throws IOException {
return this._storeFileStream(command.getCommand(), remote);
}
private OutputStream getBufferedOutputStream(OutputStream outputStream) {
return this.__bufferSize > 0 ? new BufferedOutputStream(outputStream, this.__bufferSize) : new BufferedOutputStream(outputStream);
}
protected OutputStream _storeFileStream(String command, String remote) throws IOException {
Socket socket = this._openDataConnection_(command, remote);
if (socket == null) {
return null;
} else {
Object output = socket.getOutputStream();
if (this.__fileType == 0) {
OutputStream output1 = this.getBufferedOutputStream((OutputStream) output);
output = new ToNetASCIIOutputStream(output1);
}
return new SocketOutputStream(socket, (OutputStream) output);
}
}
//上传用户身份证图片 ftp
public boolean uploadImg(String identityPath,FtpParam ftpParam, InputStream inputStream) throws IOException {
//设置上传目录
boolean flag;
logger.info("ftp uploadImg before url:" + ftpParam.getIdentityPath() + ftpParam.getSubDir() + "fileName:" + ftpParam.getFileName());
if (!changeWorkingDirectory(identityPath + ftpParam.getSubDir())) {
if (createDirectory(identityPath, ftpParam.getSubDir())) {
setControlEncoding("GBK");
setFileType(BINARY_FILE_TYPE);
setBufferSize(8 * 1024);
logger.info("ftp uploadImg storeFile url:" + ftpParam.getIdentityPath() + ftpParam.getSubDir() + "fileName:" + ftpParam.getFileName());
storeFile(new String(ftpParam.getFileName().getBytes("UTF-8"),"iso-8859-1"), inputStream);
flag = true;
} else {
flag = false;
}
} else {
setControlEncoding("GBK");
//设置文件类型(二进制)
setFileType(BINARY_FILE_TYPE);
setBufferSize(8 * 1024);
storeFile(new String(ftpParam.getFileName().getBytes("UTF-8"),"iso-8859-1"), inputStream);
flag = true;
}
logger.info("ftp uploadImg after url:" + ftpParam.getIdentityPath() + ftpParam.getSubDir() + "fileName:" + ftpParam.getFileName());
return flag;
}
//此方法不要单独使用 注意 logout(); disconnect();
public boolean createDirectory(String rootPath, String subDir) throws IOException {
changeWorkingDirectory(rootPath);
//如果远程目录不存在,则递归创建远程服务器目录
int start = 0;
int index = subDir.indexOf("/", start);
//日志记录,增加了什么目录
String addedPath = "";
while (true) {
String dir = subDir.substring(start, index);
if (!changeWorkingDirectory(new String(dir.getBytes("GBK"), "iso-8859-1"))) {
if (makeDirectory(dir)) {
addedPath +="/"+ dir;
changeWorkingDirectory(dir);
} else {
return false;
}
}
start = index + 1;
index = subDir.indexOf("/", start);
//检查所有目录是否创建完毕
if (start >= index) {
break;
}
}
logger.info("ftp createDirectory,rootPath:"+rootPath+"subDir:"+subDir+", addedPath"+addedPath);
return true;
}
/**
* Removes a non-empty directory by delete all its sub files and
* sub directories recursively. And finally remove the directory.
*/
public void removeDirectory(String parentDir,
String currentDir) throws IOException {
String dirToList = parentDir;
if (!currentDir.equals("")) {
dirToList += "/" + currentDir;
}
FTPFile[] subFiles = listFiles(dirToList);
if (subFiles != null && subFiles.length > 0) {
for (FTPFile aFile : subFiles) {
String currentFileName = aFile.getName();
if (currentFileName.equals(".") || currentFileName.equals("..")) {
// skip parent directory and the directory itself
continue;
}
String filePath = parentDir + currentDir
+ currentFileName;
if (currentDir.equals("")) {
filePath = parentDir + currentFileName;
}
if (aFile.isDirectory()) {
// remove the sub directory
removeDirectory(dirToList, currentFileName);
} else {
// delete the file
boolean deleted = deleteFile(filePath);
if (deleted) {
System.out.println("DELETED the file: " + filePath);
} else {
System.out.println("CANNOT delete the file: "
+ filePath);
}
}
}
// finally, remove the directory itself
boolean removed = removeDirectory(dirToList);
if (removed) {
System.out.println("REMOVED the directory: " + dirToList);
} else {
System.out.println("CANNOT remove the directory: " + dirToList);
}
}
}
/**
* @deprecated
*/
@Deprecated
protected Socket _openDataConnection_(int command, String arg) throws IOException {
return this._openDataConnection_(FTPCommand.getCommand(command), arg);
}
protected Socket _openDataConnection_(FTPCmd command, String arg) throws IOException {
return this._openDataConnection_(command.getCommand(), arg);
}
private void __initDefaults() {
this.__dataConnectionMode = 0;
this.__fileType = 0;
this.__fileFormat = 4;
this.__systemName = null;
}
protected void _connectAction_() throws IOException {
super._connectAction_();
this.__initDefaults();
if (this.__autodetectEncoding) {
ArrayList oldReplyLines = new ArrayList(this._replyLines);
int oldReplyCode = this._replyCode;
if (this.hasFeature("UTF8") || this.hasFeature("UTF-8")) {
this.setControlEncoding("UTF-8");
this._controlInput_ = new CRLFLineReader(new InputStreamReader(this._input_, this.getControlEncoding()));
this._controlOutput_ = new BufferedWriter(new OutputStreamWriter(this._output_, this.getControlEncoding()));
}
this._replyLines.clear();
this._replyLines.addAll(oldReplyLines);
this._replyCode = oldReplyCode;
}
}
public void disconnect() throws IOException {
super.disconnect();
this.__initDefaults();
}
public void setRemoteVerificationEnabled(boolean enable) {
this.__remoteVerificationEnabled = enable;
}
public boolean isRemoteVerificationEnabled() {
return this.__remoteVerificationEnabled;
}
public boolean login(String username, String password) throws IOException {
this.user(username);
return FTPReply.isPositiveCompletion(this._replyCode) ? true : (!FTPReply.isPositiveIntermediate(this._replyCode) ? false : FTPReply.isPositiveCompletion(this.pass(password)));
}
public boolean login(String username, String password, String account) throws IOException {
this.user(username);
if (FTPReply.isPositiveCompletion(this._replyCode)) {
return true;
} else if (!FTPReply.isPositiveIntermediate(this._replyCode)) {
return false;
} else {
this.pass(password);
return FTPReply.isPositiveCompletion(this._replyCode) ? true : (!FTPReply.isPositiveIntermediate(this._replyCode) ? false : FTPReply.isPositiveCompletion(this.acct(account)));
}
}
public boolean logout() throws IOException {
return FTPReply.isPositiveCompletion(this.quit());
}
public boolean changeWorkingDirectory(String pathname) throws IOException {
return FTPReply.isPositiveCompletion(this.cwd(pathname));
}
public boolean changeToParentDirectory() throws IOException {
return FTPReply.isPositiveCompletion(this.cdup());
}
public boolean structureMount(String pathname) throws IOException {
return FTPReply.isPositiveCompletion(this.smnt(pathname));
}
public boolean setFileType(int fileType) throws IOException {
if (FTPReply.isPositiveCompletion(this.type(fileType))) {
this.__fileType = fileType;
this.__fileFormat = 4;
return true;
} else {
return false;
}
}
public boolean setFileType(int fileType, int formatOrByteSize) throws IOException {
if (FTPReply.isPositiveCompletion(this.type(fileType, formatOrByteSize))) {
this.__fileType = fileType;
this.__fileFormat = formatOrByteSize;
return true;
} else {
return false;
}
}
public boolean remoteRetrieve(String filename) throws IOException {
return this.__dataConnectionMode != 1 && this.__dataConnectionMode != 3 ? false : FTPReply.isPositivePreliminary(this.retr(filename));
}
public boolean remoteStore(String filename) throws IOException {
return this.__dataConnectionMode != 1 && this.__dataConnectionMode != 3 ? false : FTPReply.isPositivePreliminary(this.stor(filename));
}
public boolean remoteStoreUnique(String filename) throws IOException {
return this.__dataConnectionMode != 1 && this.__dataConnectionMode != 3 ? false : FTPReply.isPositivePreliminary(this.stou(filename));
}
public boolean remoteStoreUnique() throws IOException {
return this.__dataConnectionMode != 1 && this.__dataConnectionMode != 3 ? false : FTPReply.isPositivePreliminary(this.stou());
}
public boolean remoteAppend(String filename) throws IOException {
return this.__dataConnectionMode != 1 && this.__dataConnectionMode != 3 ? false : FTPReply.isPositivePreliminary(this.appe(filename));
}
public boolean completePendingCommand() throws IOException {
return FTPReply.isPositiveCompletion(this.getReply());
}
public boolean retrieveFile(String remote, OutputStream local) throws IOException {
return this._retrieveFile(FTPCmd.RETR.getCommand(), remote, local);
}
public boolean storeFile(String remote, InputStream local) throws IOException {
return this.__storeFile(FTPCmd.STOR, remote, local);
}
public OutputStream storeFileStream(String remote) throws IOException {
return this.__storeFileStream(FTPCmd.STOR, remote);
}
public OutputStream appendFileStream(String remote) throws IOException {
return this.__storeFileStream(FTPCmd.APPE, remote);
}
public FTPFile[] mlistDir() throws IOException {
return this.mlistDir((String) null);
}
public FTPFile[] mlistDir(String pathname) throws IOException {
FTPListParseEngine engine = this.initiateMListParsing(pathname);
return engine.getFiles();
}
public FTPFile[] mlistDir(String pathname, FTPFileFilter filter) throws IOException {
FTPListParseEngine engine = this.initiateMListParsing(pathname);
return engine.getFiles(filter);
}
public boolean deleteFile(String pathname) throws IOException {
return FTPReply.isPositiveCompletion(this.dele(pathname));
}
public boolean removeDirectory(String pathname) throws IOException {
return FTPReply.isPositiveCompletion(this.rmd(pathname));
}
public boolean makeDirectory(String pathname) throws IOException {
return FTPReply.isPositiveCompletion(this.mkd(pathname));
}
public String printWorkingDirectory() throws IOException {
return this.pwd() != 257 ? null : __parsePathname((String) this._replyLines.get(this._replyLines.size() - 1));
}
public boolean sendSiteCommand(String arguments) throws IOException {
return FTPReply.isPositiveCompletion(this.site(arguments));
}
public String getSystemType() throws IOException {
if (this.__systemName == null) {
if (FTPReply.isPositiveCompletion(this.syst())) {
this.__systemName = ((String) this._replyLines.get(this._replyLines.size() - 1)).substring(4);
} else {
String systDefault = System.getProperty("org.apache.commons.net.ftp.systemType.default");
if (systDefault == null) {
throw new IOException("Unable to determine system type - response: " + this.getReplyString());
}
this.__systemName = systDefault;
}
}
return this.__systemName;
}
public String listHelp() throws IOException {
return FTPReply.isPositiveCompletion(this.help()) ? this.getReplyString() : null;
}
public String listHelp(String command) throws IOException {
return FTPReply.isPositiveCompletion(this.help(command)) ? this.getReplyString() : null;
}
public boolean sendNoOp() throws IOException {
return FTPReply.isPositiveCompletion(this.noop());
}
public String[] listNames(String pathname) throws IOException {
Socket socket = this._openDataConnection_(FTPCmd.NLST, this.getListArguments(pathname));
if (socket == null) {
return null;
} else {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), this.getControlEncoding()));
ArrayList results = new ArrayList();
String line;
while ((line = reader.readLine()) != null) {
results.add(line);
}
reader.close();
socket.close();
if (this.completePendingCommand()) {
String[] names = new String[results.size()];
return (String[]) results.toArray(names);
} else {
return null;
}
}
}
public FTPFile[] listFiles(String pathname) throws IOException {
FTPListParseEngine engine = this.initiateListParsing((String) null, pathname);
return engine.getFiles();
}
public FTPFile[] listFiles(String pathname, FTPFileFilter filter) throws IOException {
FTPListParseEngine engine = this.initiateListParsing((String) null, pathname);
return engine.getFiles(filter);
}
public FTPFile[] listDirectories(String parent) throws IOException {
return this.listFiles(parent, FTPFileFilters.DIRECTORIES);
}
public FTPListParseEngine initiateListParsing(String pathname) throws IOException {
return this.initiateListParsing((String) null, pathname);
}
private FTPListParseEngine initiateMListParsing(String pathname) throws IOException {
Socket socket = this._openDataConnection_(FTPCmd.MLSD, pathname);
FTPListParseEngine engine = new FTPListParseEngine(MLSxEntryParser.getInstance());
if (socket == null) {
return engine;
} else {
try {
engine.readServerList(socket.getInputStream(), this.getControlEncoding());
} finally {
Util.closeQuietly(socket);
this.completePendingCommand();
}
return engine;
}
}
protected String getListArguments(String pathname) {
if (this.getListHiddenFiles()) {
if (pathname != null) {
StringBuilder sb = new StringBuilder(pathname.length() + 3);
sb.append("-a ");
sb.append(pathname);
return sb.toString();
} else {
return "-a";
}
} else {
return pathname;
}
}
public void setAutodetectUTF8(boolean autodetect) {
this.__autodetectEncoding = autodetect;
}
public boolean getAutodetectUTF8() {
return this.__autodetectEncoding;
}
/**
* @deprecated
*/
@Deprecated
public String getSystemName() throws IOException {
if (this.__systemName == null && FTPReply.isPositiveCompletion(this.syst())) {
this.__systemName = ((String) this._replyLines.get(this._replyLines.size() - 1)).substring(4);
}
return this.__systemName;
}
private static class CSL implements CopyStreamListener {
private final FTPClient parent;
private final long idle;
private final int currentSoTimeout;
private long time = System.currentTimeMillis();
private int notAcked;
CSL(FTPClient parent, long idleTime, int maxWait) throws SocketException {
this.idle = idleTime;
this.parent = parent;
this.currentSoTimeout = parent.getSoTimeout();
parent.setSoTimeout(maxWait);
}
public void bytesTransferred(CopyStreamEvent event) {
this.bytesTransferred(event.getTotalBytesTransferred(), event.getBytesTransferred(), event.getStreamSize());
}
@Override
public void bytesTransferred(long l, int i, long l1) {
long now = System.currentTimeMillis();
if (now - this.time > this.idle) {
try {
this.parent.__noop();
} catch (SocketTimeoutException var9) {
++this.notAcked;
} catch (IOException e) {
logger.info("bytesTransferred Exception"+e);
}
this.time = now;
}
}
void cleanUp() throws IOException {
try {
while (this.notAcked-- > 0) {
this.parent.__getReplyNoReport();
}
} finally {
this.parent.setSoTimeout(this.currentSoTimeout);
}
}
}
}