首页

关于apache的commons-net包基于Socket实现的FTPClient功能源码分析说明

标签:ftp,apache,commons-net,FTPClient,ServerSocketFactory     发布时间:2018-02-20   

一、前言

关于apachecommons-net包中基于java.net.Socket实现的org.apache.commons.net.ftp.FTPClient、org.apache.commons.net.ftp.FTP功能,详情见下方

二、源码说明

1.FTPClient类

package org.apache.commons.net.ftp;@b@@b@import java.io.BufferedInputStream;@b@import java.io.BufferedOutputStream;@b@import java.io.BufferedReader;@b@import java.io.BufferedWriter;@b@import java.io.IOException;@b@import java.io.InputStream;@b@import java.io.InputStreamReader;@b@import java.io.OutputStream;@b@import java.io.OutputStreamWriter;@b@import java.net.Inet6Address;@b@import java.net.InetAddress;@b@import java.net.InetSocketAddress;@b@import java.net.ServerSocket;@b@import java.net.Socket;@b@import java.net.SocketException;@b@import java.net.SocketTimeoutException;@b@import java.net.UnknownHostException;@b@import java.util.ArrayList;@b@import java.util.HashMap;@b@import java.util.HashSet;@b@import java.util.Locale;@b@import java.util.Properties;@b@import java.util.Random;@b@import java.util.Set;@b@import java.util.regex.Matcher;@b@import java.util.regex.Pattern;@b@import javax.net.ServerSocketFactory;@b@import javax.net.SocketFactory;@b@import org.apache.commons.net.MalformedServerReplyException;@b@import org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory;@b@import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory;@b@import org.apache.commons.net.ftp.parser.MLSxEntryParser;@b@import org.apache.commons.net.io.CRLFLineReader;@b@import org.apache.commons.net.io.CopyStreamAdapter;@b@import org.apache.commons.net.io.CopyStreamEvent;@b@import org.apache.commons.net.io.CopyStreamListener;@b@import org.apache.commons.net.io.FromNetASCIIInputStream;@b@import org.apache.commons.net.io.SocketInputStream;@b@import org.apache.commons.net.io.SocketOutputStream;@b@import org.apache.commons.net.io.ToNetASCIIOutputStream;@b@import org.apache.commons.net.io.Util;@b@@b@public class FTPClient extends FTP@b@  implements Configurable@b@{@b@  public static final String FTP_SYSTEM_TYPE = "org.apache.commons.net.ftp.systemType";@b@  public static final String SYSTEM_TYPE_PROPERTIES = "/systemType.properties";@b@  public static final int ACTIVE_LOCAL_DATA_CONNECTION_MODE = 0;@b@  public static final int ACTIVE_REMOTE_DATA_CONNECTION_MODE = 1;@b@  public static final int PASSIVE_LOCAL_DATA_CONNECTION_MODE = 2;@b@  public static final int PASSIVE_REMOTE_DATA_CONNECTION_MODE = 3;@b@  private int __dataConnectionMode;@b@  private int __dataTimeout;@b@  private int __passivePort;@b@  private String __passiveHost;@b@  private final Random __random;@b@  private int __activeMinPort;@b@  private int __activeMaxPort;@b@  private InetAddress __activeExternalHost;@b@  private int __fileType;@b@  private int __fileFormat;@b@  private int __fileStructure;@b@  private int __fileTransferMode;@b@  private boolean __remoteVerificationEnabled;@b@  private long __restartOffset;@b@  private FTPFileEntryParserFactory __parserFactory;@b@  private int __bufferSize;@b@  private boolean __listHiddenFiles;@b@  private boolean __useEPSVwithIPv4;@b@  private String __systemName;@b@  private FTPFileEntryParser __entryParser;@b@  private String __entryParserKey;@b@  private FTPClientConfig __configuration;@b@  private CopyStreamListener __copyStreamListener;@b@  private long __controlKeepAliveTimeout;@b@  private int __controlKeepAliveReplyTimeout = 1000;@b@  private static final Pattern __PARMS_PAT = Pattern.compile("(\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3}),(\\d{1,3}),(\\d{1,3})");@b@  private boolean __autodetectEncoding = false;@b@  private HashMap<String, Set<String>> __featuresMap;@b@@b@  private static Properties getOverrideProperties()@b@  {@b@    return PropertiesSingleton.PROPERTIES;@b@  }@b@@b@  public FTPClient()@b@  {@b@    __initDefaults();@b@    this.__dataTimeout = -1;@b@    this.__remoteVerificationEnabled = true;@b@    this.__parserFactory = new DefaultFTPFileEntryParserFactory();@b@    this.__configuration = null;@b@    this.__listHiddenFiles = false;@b@    this.__useEPSVwithIPv4 = false;@b@    this.__random = new Random();@b@  }@b@@b@  private void __initDefaults()@b@  {@b@    this.__dataConnectionMode = 0;@b@    this.__passiveHost = null;@b@    this.__passivePort = -1;@b@    this.__activeExternalHost = null;@b@    this.__activeMinPort = 0;@b@    this.__activeMaxPort = 0;@b@    this.__fileType = 0;@b@    this.__fileStructure = 7;@b@    this.__fileFormat = 4;@b@    this.__fileTransferMode = 10;@b@    this.__restartOffset = 0L;@b@    this.__systemName = null;@b@    this.__entryParser = null;@b@    this.__entryParserKey = "";@b@    this.__bufferSize = 1024;@b@    this.__featuresMap = null;@b@  }@b@@b@  private String __parsePathname(String reply)@b@  {@b@    int begin = reply.indexOf(34) + 1;@b@    int end = reply.indexOf(34, begin);@b@@b@    return reply.substring(begin, end);@b@  }@b@@b@  private void __parsePassiveModeReply(String reply)@b@    throws MalformedServerReplyException@b@  {@b@    Matcher m = __PARMS_PAT.matcher(reply);@b@    if (!(m.find())) {@b@      throw new MalformedServerReplyException("Could not parse passive host information.\nServer Reply: " + reply);@b@    }@b@@b@    this.__passiveHost = m.group(1).replace(',', '.');@b@    try@b@    {@b@      int oct1 = Integer.parseInt(m.group(2));@b@      int oct2 = Integer.parseInt(m.group(3));@b@      this.__passivePort = (oct1 << 8 | oct2);@b@    }@b@    catch (NumberFormatException e)@b@    {@b@      throw new MalformedServerReplyException("Could not parse passive port information.\nServer Reply: " + reply);@b@    }@b@@b@    try@b@    {@b@      InetAddress host = InetAddress.getByName(this.__passiveHost);@b@@b@      if ((host.isSiteLocalAddress()) && (!(getRemoteAddress().isSiteLocalAddress()))) {@b@        String hostAddress = getRemoteAddress().getHostAddress();@b@        fireReplyReceived(0, "[Replacing site local address " + this.__passiveHost + " with " + hostAddress + "]\n");@b@@b@        this.__passiveHost = hostAddress;@b@      }@b@    } catch (UnknownHostException e) {@b@      throw new MalformedServerReplyException("Could not parse passive host information.\nServer Reply: " + reply);@b@    }@b@  }@b@@b@  private void __parseExtendedPassiveModeReply(String reply)@b@    throws MalformedServerReplyException@b@  {@b@    int port;@b@    reply = reply.substring(reply.indexOf(40) + 1, reply.indexOf(41)).trim();@b@@b@    char delim1 = reply.charAt(0);@b@    char delim2 = reply.charAt(1);@b@    char delim3 = reply.charAt(2);@b@    char delim4 = reply.charAt(reply.length() - 1);@b@@b@    if ((delim1 != delim2) || (delim2 != delim3) || (delim3 != delim4))@b@    {@b@      throw new MalformedServerReplyException("Could not parse extended passive host information.\nServer Reply: " + reply);@b@    }@b@    try@b@    {@b@      port = Integer.parseInt(reply.substring(3, reply.length() - 1));@b@    }@b@    catch (NumberFormatException e)@b@    {@b@      throw new MalformedServerReplyException("Could not parse extended passive host information.\nServer Reply: " + reply);@b@    }@b@@b@    this.__passiveHost = getRemoteAddress().getHostAddress();@b@    this.__passivePort = port;@b@  }@b@@b@  private boolean __storeFile(int command, String remote, InputStream local)@b@    throws IOException@b@  {@b@    Socket socket;@b@    if ((socket = _openDataConnection_(command, remote)) == null)@b@      return false;@b@@b@    OutputStream output = new BufferedOutputStream(socket.getOutputStream(), getBufferSize());@b@@b@    if (this.__fileType == 0)@b@      output = new ToNetASCIIOutputStream(output);@b@@b@    CSL csl = null;@b@    if (this.__controlKeepAliveTimeout > 0L) {@b@      csl = new CSL(this, this.__controlKeepAliveTimeout, this.__controlKeepAliveReplyTimeout);@b@    }@b@@b@    try@b@    {@b@      Util.copyStream(local, output, getBufferSize(), -1L, __mergeListeners(csl), false);@b@    }@b@    finally@b@    {@b@      Util.closeQuietly(socket);@b@    }@b@@b@    boolean ok = completePendingCommand();@b@    if (csl != null)@b@      csl.cleanUp();@b@@b@    output.close();@b@    return ok;@b@  }@b@@b@  private OutputStream __storeFileStream(int command, String remote)@b@    throws IOException@b@  {@b@    Socket socket;@b@    if ((socket = _openDataConnection_(command, remote)) == null)@b@      return null;@b@@b@    OutputStream output = socket.getOutputStream();@b@    if (this.__fileType == 0)@b@    {@b@      output = new BufferedOutputStream(output, getBufferSize());@b@@b@      output = new ToNetASCIIOutputStream(output);@b@    }@b@@b@    return new SocketOutputStream(socket, output);@b@  }@b@@b@  protected Socket _openDataConnection_(int command, String arg)@b@    throws IOException@b@  {@b@    label108: Socket socket;@b@    if ((this.__dataConnectionMode != 0) && (this.__dataConnectionMode != 2))@b@    {@b@      return null;@b@    }@b@    boolean isInet6Address = getRemoteAddress() instanceof Inet6Address;@b@@b@    if (this.__dataConnectionMode == 0)@b@    {@b@      ServerSocket server = this._serverSocketFactory_.createServerSocket(getActivePort(), 1, getHostAddress());@b@@b@      if (isInet6Address)@b@      {@b@        if (FTPReply.isPositiveCompletion(eprt(getHostAddress(), server.getLocalPort())))@b@          break label108;@b@        server.close();@b@        return null;@b@      }@b@@b@      if (!(FTPReply.isPositiveCompletion(port(getHostAddress(), server.getLocalPort()))))@b@      {@b@        server.close();@b@        return null;@b@      }@b@@b@      if ((this.__restartOffset > 0L) && (!(restart(this.__restartOffset))))@b@      {@b@        server.close();@b@        return null;@b@      }@b@@b@      if (!(FTPReply.isPositivePreliminary(sendCommand(command, arg))))@b@      {@b@        server.close();@b@        return null;@b@      }@b@@b@      if (this.__dataTimeout >= 0)@b@        server.setSoTimeout(this.__dataTimeout);@b@      try {@b@        socket = server.accept();@b@      } finally {@b@        server.close();@b@      }@b@@b@    }@b@    else@b@    {@b@      boolean attemptEPSV = (isUseEPSVwithIPv4()) || (isInet6Address);@b@      if ((attemptEPSV) && (epsv() == 229))@b@      {@b@        __parseExtendedPassiveModeReply((String)this._replyLines.get(0));@b@      }@b@      else@b@      {@b@        if (isInet6Address) {@b@          return null;@b@        }@b@@b@        if (pasv() != 227)@b@          return null;@b@@b@        __parsePassiveModeReply((String)this._replyLines.get(0));@b@      }@b@@b@      socket = this._socketFactory_.createSocket();@b@      socket.connect(new InetSocketAddress(this.__passiveHost, this.__passivePort), this.connectTimeout);@b@      if ((this.__restartOffset > 0L) && (!(restart(this.__restartOffset))))@b@      {@b@        socket.close();@b@        return null;@b@      }@b@@b@      if (!(FTPReply.isPositivePreliminary(sendCommand(command, arg))))@b@      {@b@        socket.close();@b@        return null;@b@      }@b@    }@b@@b@    if ((this.__remoteVerificationEnabled) && (!(verifyRemote(socket))))@b@    {@b@      InetAddress host1 = socket.getInetAddress();@b@      InetAddress host2 = getRemoteAddress();@b@@b@      socket.close();@b@@b@      throw new IOException("Host attempting data connection " + host1.getHostAddress() + " is not same as server " + host2.getHostAddress());@b@    }@b@@b@    if (this.__dataTimeout >= 0)@b@      socket.setSoTimeout(this.__dataTimeout);@b@@b@    return socket;@b@  }@b@@b@  protected void _connectAction_()@b@    throws IOException@b@  {@b@    super._connectAction_();@b@    __initDefaults();@b@@b@    if (this.__autodetectEncoding)@b@    {@b@      ArrayList oldReplyLines = new ArrayList(this._replyLines);@b@      int oldReplyCode = this._replyCode;@b@      if ((hasFeature("UTF8")) || (hasFeature("UTF-8")))@b@      {@b@        setControlEncoding("UTF-8");@b@        this._controlInput_ = new CRLFLineReader(new InputStreamReader(this._input_, getControlEncoding()));@b@@b@        this._controlOutput_ = new BufferedWriter(new OutputStreamWriter(this._output_, getControlEncoding()));@b@      }@b@@b@      this._replyLines.clear();@b@      this._replyLines.addAll(oldReplyLines);@b@      this._replyCode = oldReplyCode;@b@    }@b@  }@b@@b@  public void setDataTimeout(int timeout)@b@  {@b@    this.__dataTimeout = timeout;@b@  }@b@@b@  public void setParserFactory(FTPFileEntryParserFactory parserFactory)@b@  {@b@    this.__parserFactory = parserFactory;@b@  }@b@@b@  public void disconnect()@b@    throws IOException@b@  {@b@    super.disconnect();@b@    __initDefaults();@b@  }@b@@b@  public void setRemoteVerificationEnabled(boolean enable)@b@  {@b@    this.__remoteVerificationEnabled = enable;@b@  }@b@@b@  public boolean isRemoteVerificationEnabled()@b@  {@b@    return this.__remoteVerificationEnabled;@b@  }@b@@b@  public boolean login(String username, String password)@b@    throws IOException@b@  {@b@    user(username);@b@@b@    if (FTPReply.isPositiveCompletion(this._replyCode)) {@b@      return true;@b@    }@b@@b@    if (!(FTPReply.isPositiveIntermediate(this._replyCode)))@b@      return false;@b@@b@    return FTPReply.isPositiveCompletion(pass(password));@b@  }@b@@b@  public boolean login(String username, String password, String account)@b@    throws IOException@b@  {@b@    user(username);@b@@b@    if (FTPReply.isPositiveCompletion(this._replyCode)) {@b@      return true;@b@    }@b@@b@    if (!(FTPReply.isPositiveIntermediate(this._replyCode)))@b@      return false;@b@@b@    pass(password);@b@@b@    if (FTPReply.isPositiveCompletion(this._replyCode))@b@      return true;@b@@b@    if (!(FTPReply.isPositiveIntermediate(this._replyCode)))@b@      return false;@b@@b@    return FTPReply.isPositiveCompletion(acct(account));@b@  }@b@@b@  public boolean logout()@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(quit());@b@  }@b@@b@  public boolean changeWorkingDirectory(String pathname)@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(cwd(pathname));@b@  }@b@@b@  public boolean changeToParentDirectory()@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(cdup());@b@  }@b@@b@  public boolean structureMount(String pathname)@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(smnt(pathname));@b@  }@b@@b@  boolean reinitialize()@b@    throws IOException@b@  {@b@    rein();@b@@b@    if ((FTPReply.isPositiveCompletion(this._replyCode)) || ((FTPReply.isPositivePreliminary(this._replyCode)) && (FTPReply.isPositiveCompletion(getReply()))))@b@    {@b@      __initDefaults();@b@@b@      return true;@b@    }@b@@b@    return false;@b@  }@b@@b@  public void enterLocalActiveMode()@b@  {@b@    this.__dataConnectionMode = 0;@b@    this.__passiveHost = null;@b@    this.__passivePort = -1;@b@  }@b@@b@  public void enterLocalPassiveMode()@b@  {@b@    this.__dataConnectionMode = 2;@b@@b@    this.__passiveHost = null;@b@    this.__passivePort = -1;@b@  }@b@@b@  public boolean enterRemoteActiveMode(InetAddress host, int port)@b@    throws IOException@b@  {@b@    if (FTPReply.isPositiveCompletion(port(host, port)))@b@    {@b@      this.__dataConnectionMode = 1;@b@      this.__passiveHost = null;@b@      this.__passivePort = -1;@b@      return true;@b@    }@b@    return false;@b@  }@b@@b@  public boolean enterRemotePassiveMode()@b@    throws IOException@b@  {@b@    if (pasv() != 227)@b@      return false;@b@@b@    this.__dataConnectionMode = 3;@b@    __parsePassiveModeReply((String)this._replyLines.get(0));@b@@b@    return true;@b@  }@b@@b@  public String getPassiveHost()@b@  {@b@    return this.__passiveHost;@b@  }@b@@b@  public int getPassivePort()@b@  {@b@    return this.__passivePort;@b@  }@b@@b@  public int getDataConnectionMode()@b@  {@b@    return this.__dataConnectionMode;@b@  }@b@@b@  private int getActivePort()@b@  {@b@    if ((this.__activeMinPort > 0) && (this.__activeMaxPort >= this.__activeMinPort))@b@    {@b@      if (this.__activeMaxPort == this.__activeMinPort)@b@        return this.__activeMaxPort;@b@@b@      return (this.__random.nextInt(this.__activeMaxPort - this.__activeMinPort + 1) + this.__activeMinPort);@b@    }@b@@b@    return 0;@b@  }@b@@b@  private InetAddress getHostAddress()@b@  {@b@    if (this.__activeExternalHost != null)@b@    {@b@      return this.__activeExternalHost;@b@    }@b@@b@    return getLocalAddress();@b@  }@b@@b@  public void setActivePortRange(int minPort, int maxPort)@b@  {@b@    this.__activeMinPort = minPort;@b@    this.__activeMaxPort = maxPort;@b@  }@b@@b@  public void setActiveExternalIPAddress(String ipAddress)@b@    throws UnknownHostException@b@  {@b@    this.__activeExternalHost = InetAddress.getByName(ipAddress);@b@  }@b@@b@  public boolean setFileType(int fileType)@b@    throws IOException@b@  {@b@    if (FTPReply.isPositiveCompletion(type(fileType)))@b@    {@b@      this.__fileType = fileType;@b@      this.__fileFormat = 4;@b@      return true;@b@    }@b@    return false;@b@  }@b@@b@  public boolean setFileType(int fileType, int formatOrByteSize)@b@    throws IOException@b@  {@b@    if (FTPReply.isPositiveCompletion(type(fileType, formatOrByteSize)))@b@    {@b@      this.__fileType = fileType;@b@      this.__fileFormat = formatOrByteSize;@b@      return true;@b@    }@b@    return false;@b@  }@b@@b@  public boolean setFileStructure(int structure)@b@    throws IOException@b@  {@b@    if (FTPReply.isPositiveCompletion(stru(structure)))@b@    {@b@      this.__fileStructure = structure;@b@      return true;@b@    }@b@    return false;@b@  }@b@@b@  public boolean setFileTransferMode(int mode)@b@    throws IOException@b@  {@b@    if (FTPReply.isPositiveCompletion(mode(mode)))@b@    {@b@      this.__fileTransferMode = mode;@b@      return true;@b@    }@b@    return false;@b@  }@b@@b@  public boolean remoteRetrieve(String filename)@b@    throws IOException@b@  {@b@    if ((this.__dataConnectionMode == 1) || (this.__dataConnectionMode == 3))@b@    {@b@      return FTPReply.isPositivePreliminary(retr(filename)); }@b@    return false;@b@  }@b@@b@  public boolean remoteStore(String filename)@b@    throws IOException@b@  {@b@    if ((this.__dataConnectionMode == 1) || (this.__dataConnectionMode == 3))@b@    {@b@      return FTPReply.isPositivePreliminary(stor(filename)); }@b@    return false;@b@  }@b@@b@  public boolean remoteStoreUnique(String filename)@b@    throws IOException@b@  {@b@    if ((this.__dataConnectionMode == 1) || (this.__dataConnectionMode == 3))@b@    {@b@      return FTPReply.isPositivePreliminary(stou(filename)); }@b@    return false;@b@  }@b@@b@  public boolean remoteStoreUnique()@b@    throws IOException@b@  {@b@    if ((this.__dataConnectionMode == 1) || (this.__dataConnectionMode == 3))@b@    {@b@      return FTPReply.isPositivePreliminary(stou()); }@b@    return false;@b@  }@b@@b@  public boolean remoteAppend(String filename)@b@    throws IOException@b@  {@b@    if ((this.__dataConnectionMode == 1) || (this.__dataConnectionMode == 3))@b@    {@b@      return FTPReply.isPositivePreliminary(appe(filename)); }@b@    return false;@b@  }@b@@b@  public boolean completePendingCommand()@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(getReply());@b@  }@b@@b@  public boolean retrieveFile(String remote, OutputStream local)@b@    throws IOException@b@  {@b@    Socket socket;@b@    if ((socket = _openDataConnection_(13, remote)) == null)@b@      return false;@b@@b@    InputStream input = new BufferedInputStream(socket.getInputStream(), getBufferSize());@b@@b@    if (this.__fileType == 0)@b@      input = new FromNetASCIIInputStream(input);@b@@b@    CSL csl = null;@b@    if (this.__controlKeepAliveTimeout > 0L) {@b@      csl = new CSL(this, this.__controlKeepAliveTimeout, this.__controlKeepAliveReplyTimeout);@b@    }@b@@b@    try@b@    {@b@      Util.copyStream(input, local, getBufferSize(), -1L, __mergeListeners(csl), false);@b@    }@b@    finally@b@    {@b@      Util.closeQuietly(socket);@b@    }@b@@b@    boolean ok = completePendingCommand();@b@    if (csl != null)@b@      csl.cleanUp();@b@@b@    return ok;@b@  }@b@@b@  public InputStream retrieveFileStream(String remote)@b@    throws IOException@b@  {@b@    Socket socket;@b@    if ((socket = _openDataConnection_(13, remote)) == null)@b@      return null;@b@@b@    InputStream input = socket.getInputStream();@b@    if (this.__fileType == 0)@b@    {@b@      input = new BufferedInputStream(input, getBufferSize());@b@@b@      input = new FromNetASCIIInputStream(input);@b@    }@b@    return new SocketInputStream(socket, input);@b@  }@b@@b@  public boolean storeFile(String remote, InputStream local)@b@    throws IOException@b@  {@b@    return __storeFile(14, remote, local);@b@  }@b@@b@  public OutputStream storeFileStream(String remote)@b@    throws IOException@b@  {@b@    return __storeFileStream(14, remote);@b@  }@b@@b@  public boolean appendFile(String remote, InputStream local)@b@    throws IOException@b@  {@b@    return __storeFile(16, remote, local);@b@  }@b@@b@  public OutputStream appendFileStream(String remote)@b@    throws IOException@b@  {@b@    return __storeFileStream(16, remote);@b@  }@b@@b@  public boolean storeUniqueFile(String remote, InputStream local)@b@    throws IOException@b@  {@b@    return __storeFile(15, remote, local);@b@  }@b@@b@  public OutputStream storeUniqueFileStream(String remote)@b@    throws IOException@b@  {@b@    return __storeFileStream(15, remote);@b@  }@b@@b@  public boolean storeUniqueFile(InputStream local)@b@    throws IOException@b@  {@b@    return __storeFile(15, null, local);@b@  }@b@@b@  public OutputStream storeUniqueFileStream()@b@    throws IOException@b@  {@b@    return __storeFileStream(15, null);@b@  }@b@@b@  public boolean allocate(int bytes)@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(allo(bytes));@b@  }@b@@b@  public boolean features()@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(feat());@b@  }@b@@b@  public String[] featureValues(String feature)@b@    throws IOException@b@  {@b@    if (!(initFeatureMap()))@b@      return null;@b@@b@    Set entries = (Set)this.__featuresMap.get(feature.toUpperCase(Locale.ENGLISH));@b@    if (entries != null)@b@      return ((String[])entries.toArray(new String[entries.size()]));@b@@b@    return null;@b@  }@b@@b@  public String featureValue(String feature)@b@    throws IOException@b@  {@b@    String[] values = featureValues(feature);@b@    if (values != null)@b@      return values[0];@b@@b@    return null;@b@  }@b@@b@  public boolean hasFeature(String feature)@b@    throws IOException@b@  {@b@    if (!(initFeatureMap()))@b@      return false;@b@@b@    return this.__featuresMap.containsKey(feature.toUpperCase(Locale.ENGLISH));@b@  }@b@@b@  public boolean hasFeature(String feature, String value)@b@    throws IOException@b@  {@b@    if (!(initFeatureMap()))@b@      return false;@b@@b@    Set entries = (Set)this.__featuresMap.get(feature.toUpperCase(Locale.ENGLISH));@b@    if (entries != null)@b@      return entries.contains(value);@b@@b@    return false;@b@  }@b@@b@  private boolean initFeatureMap()@b@    throws IOException@b@  {@b@    String[] arr$;@b@    int i$;@b@    if (this.__featuresMap == null)@b@    {@b@      boolean success = FTPReply.isPositiveCompletion(feat());@b@@b@      this.__featuresMap = new HashMap();@b@      if (!(success))@b@        return false;@b@@b@      arr$ = getReplyStrings(); int len$ = arr$.length; for (i$ = 0; i$ < len$; ++i$) { String l = arr$[i$];@b@        if (l.startsWith(" "))@b@        {@b@          String value = "";@b@          int varsep = l.indexOf(32, 1);@b@          if (varsep > 0) {@b@            key = l.substring(1, varsep);@b@            value = l.substring(varsep + 1);@b@          } else {@b@            key = l.substring(1);@b@          }@b@          String key = key.toUpperCase(Locale.ENGLISH);@b@          Set entries = (Set)this.__featuresMap.get(key);@b@          if (entries == null) {@b@            entries = new HashSet();@b@            this.__featuresMap.put(key, entries);@b@          }@b@          entries.add(value);@b@        }@b@      }@b@    }@b@    return true;@b@  }@b@@b@  public boolean allocate(int bytes, int recordSize)@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(allo(bytes, recordSize));@b@  }@b@@b@  public boolean doCommand(String command, String params)@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(sendCommand(command, params));@b@  }@b@@b@  public String[] doCommandAsStrings(String command, String params)@b@    throws IOException@b@  {@b@    boolean success = FTPReply.isPositiveCompletion(sendCommand(command, params));@b@    if (success)@b@      return getReplyStrings();@b@@b@    return null;@b@  }@b@@b@  public FTPFile mlistFile(String pathname)@b@    throws IOException@b@  {@b@    boolean success = FTPReply.isPositiveCompletion(sendCommand(39, pathname));@b@    if (success) {@b@      String entry = getReplyStrings()[1].substring(1);@b@      return MLSxEntryParser.parseEntry(entry);@b@    }@b@    return null;@b@  }@b@@b@  public FTPFile[] mlistDir()@b@    throws IOException@b@  {@b@    return mlistDir(null);@b@  }@b@@b@  public FTPFile[] mlistDir(String pathname)@b@    throws IOException@b@  {@b@    FTPListParseEngine engine = initiateMListParsing(pathname);@b@    return engine.getFiles();@b@  }@b@@b@  public FTPFile[] mlistDir(String pathname, FTPFileFilter filter)@b@    throws IOException@b@  {@b@    FTPListParseEngine engine = initiateMListParsing(pathname);@b@    return engine.getFiles(filter);@b@  }@b@@b@  private boolean restart(long offset)@b@    throws IOException@b@  {@b@    this.__restartOffset = 0L;@b@    return FTPReply.isPositiveIntermediate(rest(Long.toString(offset)));@b@  }@b@@b@  public void setRestartOffset(long offset)@b@  {@b@    if (offset >= 0L)@b@      this.__restartOffset = offset;@b@  }@b@@b@  public long getRestartOffset()@b@  {@b@    return this.__restartOffset;@b@  }@b@@b@  public boolean rename(String from, String to)@b@    throws IOException@b@  {@b@    if (!(FTPReply.isPositiveIntermediate(rnfr(from))))@b@      return false;@b@@b@    return FTPReply.isPositiveCompletion(rnto(to));@b@  }@b@@b@  public boolean abort()@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(abor());@b@  }@b@@b@  public boolean deleteFile(String pathname)@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(dele(pathname));@b@  }@b@@b@  public boolean removeDirectory(String pathname)@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(rmd(pathname));@b@  }@b@@b@  public boolean makeDirectory(String pathname)@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(mkd(pathname));@b@  }@b@@b@  public String printWorkingDirectory()@b@    throws IOException@b@  {@b@    if (pwd() != 257)@b@      return null;@b@@b@    return __parsePathname((String)this._replyLines.get(this._replyLines.size() - 1));@b@  }@b@@b@  public boolean sendSiteCommand(String arguments)@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(site(arguments));@b@  }@b@@b@  public String getSystemType()@b@    throws IOException@b@  {@b@    if (this.__systemName == null)@b@      if (FTPReply.isPositiveCompletion(syst()))@b@      {@b@        this.__systemName = ((String)this._replyLines.get(this._replyLines.size() - 1)).substring(4);@b@      }@b@      else throw new IOException("Unable to determine system type - response: " + getReplyString());@b@@b@@b@    return this.__systemName;@b@  }@b@@b@  public String listHelp()@b@    throws IOException@b@  {@b@    if (FTPReply.isPositiveCompletion(help()))@b@      return getReplyString();@b@    return null;@b@  }@b@@b@  public String listHelp(String command)@b@    throws IOException@b@  {@b@    if (FTPReply.isPositiveCompletion(help(command)))@b@      return getReplyString();@b@    return null;@b@  }@b@@b@  public boolean sendNoOp()@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(noop());@b@  }@b@@b@  public String[] listNames(String pathname)@b@    throws IOException@b@  {@b@    Socket socket;@b@    if ((socket = _openDataConnection_(27, getListArguments(pathname))) == null)@b@      return null;@b@@b@    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), getControlEncoding()));@b@@b@    ArrayList results = new ArrayList();@b@    while ((line = reader.readLine()) != null) {@b@      String line;@b@      results.add(line);@b@    }@b@    reader.close();@b@    socket.close();@b@@b@    if (completePendingCommand())@b@    {@b@      String[] names = new String[results.size()];@b@      return ((String[])results.toArray(names));@b@    }@b@@b@    return null;@b@  }@b@@b@  public String[] listNames()@b@    throws IOException@b@  {@b@    return listNames(null);@b@  }@b@@b@  public FTPFile[] listFiles(String pathname)@b@    throws IOException@b@  {@b@    FTPListParseEngine engine = initiateListParsing((String)null, pathname);@b@    return engine.getFiles();@b@  }@b@@b@  public FTPFile[] listFiles()@b@    throws IOException@b@  {@b@    return listFiles((String)null);@b@  }@b@@b@  public FTPFile[] listFiles(String pathname, FTPFileFilter filter)@b@    throws IOException@b@  {@b@    FTPListParseEngine engine = initiateListParsing((String)null, pathname);@b@    return engine.getFiles(filter);@b@  }@b@@b@  public FTPFile[] listDirectories()@b@    throws IOException@b@  {@b@    return listDirectories((String)null);@b@  }@b@@b@  public FTPFile[] listDirectories(String parent)@b@    throws IOException@b@  {@b@    return listFiles(parent, FTPFileFilters.DIRECTORIES);@b@  }@b@@b@  public FTPListParseEngine initiateListParsing()@b@    throws IOException@b@  {@b@    return initiateListParsing((String)null);@b@  }@b@@b@  public FTPListParseEngine initiateListParsing(String pathname)@b@    throws IOException@b@  {@b@    String key = null;@b@    return initiateListParsing(key, pathname);@b@  }@b@@b@  public FTPListParseEngine initiateListParsing(String parserKey, String pathname)@b@    throws IOException@b@  {@b@    if ((this.__entryParser == null) || (!(this.__entryParserKey.equals(parserKey)))) {@b@      if (null != parserKey)@b@      {@b@        this.__entryParser = this.__parserFactory.createFileEntryParser(parserKey);@b@@b@        this.__entryParserKey = parserKey;@b@      }@b@      else if (null != this.__configuration) {@b@        this.__entryParser = this.__parserFactory.createFileEntryParser(this.__configuration);@b@@b@        this.__entryParserKey = this.__configuration.getServerSystemKey();@b@      }@b@      else@b@      {@b@        String systemType = System.getProperty("org.apache.commons.net.ftp.systemType");@b@        if (systemType == null) {@b@          systemType = getSystemType();@b@          Properties override = getOverrideProperties();@b@          if (override != null) {@b@            String newType = override.getProperty(systemType);@b@            if (newType != null)@b@              systemType = newType;@b@          }@b@        }@b@@b@        this.__entryParser = this.__parserFactory.createFileEntryParser(systemType);@b@        this.__entryParserKey = systemType;@b@      }@b@@b@    }@b@@b@    return initiateListParsing(this.__entryParser, pathname);@b@  }@b@@b@  private FTPListParseEngine initiateListParsing(FTPFileEntryParser parser, String pathname)@b@    throws IOException@b@  {@b@    Socket socket;@b@    FTPListParseEngine engine = new FTPListParseEngine(parser);@b@    if ((socket = _openDataConnection_(26, getListArguments(pathname))) == null)@b@    {@b@      return engine;@b@    }@b@    try@b@    {@b@      engine.readServerList(socket.getInputStream(), getControlEncoding());@b@    }@b@    finally {@b@      Util.closeQuietly(socket);@b@    }@b@@b@    completePendingCommand();@b@    return engine;@b@  }@b@@b@  private FTPListParseEngine initiateMListParsing(String pathname)@b@    throws IOException@b@  {@b@    Socket socket;@b@    FTPListParseEngine engine = new FTPListParseEngine(MLSxEntryParser.getInstance());@b@    if ((socket = _openDataConnection_(38, pathname)) == null)@b@    {@b@      return engine;@b@    }@b@    try@b@    {@b@      engine.readServerList(socket.getInputStream(), getControlEncoding());@b@    }@b@    finally {@b@      Util.closeQuietly(socket);@b@      completePendingCommand();@b@    }@b@    return engine;@b@  }@b@@b@  protected String getListArguments(String pathname)@b@  {@b@    if (getListHiddenFiles())@b@    {@b@      if (pathname != null)@b@      {@b@        StringBuilder sb = new StringBuilder(pathname.length() + 3);@b@        sb.append("-a ");@b@        sb.append(pathname);@b@        return sb.toString();@b@      }@b@@b@      return "-a";@b@    }@b@@b@    return pathname;@b@  }@b@@b@  public String getStatus()@b@    throws IOException@b@  {@b@    if (FTPReply.isPositiveCompletion(stat()))@b@      return getReplyString();@b@    return null;@b@  }@b@@b@  public String getStatus(String pathname)@b@    throws IOException@b@  {@b@    if (FTPReply.isPositiveCompletion(stat(pathname)))@b@      return getReplyString();@b@    return null;@b@  }@b@@b@  public String getModificationTime(String pathname)@b@    throws IOException@b@  {@b@    if (FTPReply.isPositiveCompletion(mdtm(pathname)))@b@      return getReplyString();@b@    return null;@b@  }@b@@b@  public boolean setModificationTime(String pathname, String timeval)@b@    throws IOException@b@  {@b@    return FTPReply.isPositiveCompletion(mfmt(pathname, timeval));@b@  }@b@@b@  public void setBufferSize(int bufSize)@b@  {@b@    this.__bufferSize = bufSize;@b@  }@b@@b@  public int getBufferSize()@b@  {@b@    return this.__bufferSize;@b@  }@b@@b@  public void configure(FTPClientConfig config)@b@  {@b@    this.__configuration = config;@b@  }@b@@b@  public void setListHiddenFiles(boolean listHiddenFiles)@b@  {@b@    this.__listHiddenFiles = listHiddenFiles;@b@  }@b@@b@  public boolean getListHiddenFiles()@b@  {@b@    return this.__listHiddenFiles;@b@  }@b@@b@  public boolean isUseEPSVwithIPv4()@b@  {@b@    return this.__useEPSVwithIPv4;@b@  }@b@@b@  public void setUseEPSVwithIPv4(boolean selected)@b@  {@b@    this.__useEPSVwithIPv4 = selected;@b@  }@b@@b@  public void setCopyStreamListener(CopyStreamListener listener)@b@  {@b@    this.__copyStreamListener = listener;@b@  }@b@@b@  public CopyStreamListener getCopyStreamListener()@b@  {@b@    return this.__copyStreamListener;@b@  }@b@@b@  public void setControlKeepAliveTimeout(long controlIdle)@b@  {@b@    this.__controlKeepAliveTimeout = (controlIdle * 1000L);@b@  }@b@@b@  public long getControlKeepAliveTimeout()@b@  {@b@    return (this.__controlKeepAliveTimeout / 1000L);@b@  }@b@@b@  public void setControlKeepAliveReplyTimeout(int timeout)@b@  {@b@    this.__controlKeepAliveReplyTimeout = timeout;@b@  }@b@@b@  public int getControlKeepAliveReplyTimeout()@b@  {@b@    return this.__controlKeepAliveReplyTimeout;@b@  }@b@@b@  private CopyStreamListener __mergeListeners(CopyStreamListener local)@b@  {@b@    if (local == null)@b@      return this.__copyStreamListener;@b@@b@    if (this.__copyStreamListener == null) {@b@      return local;@b@    }@b@@b@    CopyStreamAdapter merged = new CopyStreamAdapter();@b@    merged.addCopyStreamListener(local);@b@    merged.addCopyStreamListener(this.__copyStreamListener);@b@    return merged;@b@  }@b@@b@  public void setAutodetectUTF8(boolean autodetect)@b@  {@b@    this.__autodetectEncoding = autodetect;@b@  }@b@@b@  public boolean getAutodetectUTF8()@b@  {@b@    return this.__autodetectEncoding;@b@  }@b@@b@  @Deprecated@b@  public String getSystemName()@b@    throws IOException@b@  {@b@    if ((this.__systemName == null) && (FTPReply.isPositiveCompletion(syst())))@b@      this.__systemName = ((String)this._replyLines.get(this._replyLines.size() - 1)).substring(4);@b@    return this.__systemName;@b@  }@b@@b@  private static class CSL@b@    implements CopyStreamListener@b@  {@b@    private final FTPClient parent;@b@    private final long idle;@b@    private final int currentSoTimeout;@b@    private long time = System.currentTimeMillis();@b@    private int notAcked;@b@@b@    CSL(FTPClient parent, long idleTime, int maxWait)@b@      throws SocketException@b@    {@b@      this.idle = idleTime;@b@      this.parent = parent;@b@      this.currentSoTimeout = parent.getSoTimeout();@b@      parent.setSoTimeout(maxWait); }@b@@b@    public void bytesTransferred(CopyStreamEvent event) {@b@      bytesTransferred(event.getTotalBytesTransferred(), event.getBytesTransferred(), event.getStreamSize());@b@    }@b@@b@    public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize)@b@    {@b@      long now = System.currentTimeMillis();@b@      if (now - this.time > this.idle) {@b@        try {@b@          this.parent.__noop();@b@        } catch (SocketTimeoutException e) {@b@          this.notAcked += 1;@b@        } catch (IOException e) {@b@        }@b@        this.time = now;@b@      }@b@    }@b@@b@    void cleanUp() throws IOException {@b@      while (this.notAcked-- > 0)@b@        this.parent.__getReplyNoReport();@b@@b@      this.parent.setSoTimeout(this.currentSoTimeout);@b@    }@b@  }@b@@b@  private static class PropertiesSingleton@b@  {@b@    static final Properties PROPERTIES;@b@@b@    static@b@    {@b@      InputStream resourceAsStream = FTPClient.class.getResourceAsStream("/systemType.properties");@b@      Properties p = null;@b@      if (resourceAsStream != null) {@b@        p = new Properties();@b@        try {@b@          p.load(resourceAsStream);@b@        } catch (IOException e) {@b@        } finally {@b@          try {@b@            resourceAsStream.close();@b@          }@b@          catch (IOException e) {@b@          }@b@        }@b@      }@b@      PROPERTIES = p;@b@    }@b@  }@b@}

2.FTP类

package org.apache.commons.net.ftp;@b@@b@import java.io.BufferedReader;@b@import java.io.BufferedWriter;@b@import java.io.IOException;@b@import java.io.InputStreamReader;@b@import java.io.OutputStreamWriter;@b@import java.net.Inet4Address;@b@import java.net.Inet6Address;@b@import java.net.InetAddress;@b@import java.net.Socket;@b@import java.net.SocketException;@b@import java.net.SocketTimeoutException;@b@import java.util.ArrayList;@b@import org.apache.commons.net.MalformedServerReplyException;@b@import org.apache.commons.net.ProtocolCommandSupport;@b@import org.apache.commons.net.SocketClient;@b@import org.apache.commons.net.io.CRLFLineReader;@b@@b@public class FTP extends SocketClient@b@{@b@  public static final int DEFAULT_DATA_PORT = 20;@b@  public static final int DEFAULT_PORT = 21;@b@  public static final int ASCII_FILE_TYPE = 0;@b@  public static final int EBCDIC_FILE_TYPE = 1;@b@  public static final int BINARY_FILE_TYPE = 2;@b@  public static final int LOCAL_FILE_TYPE = 3;@b@  public static final int NON_PRINT_TEXT_FORMAT = 4;@b@  public static final int TELNET_TEXT_FORMAT = 5;@b@  public static final int CARRIAGE_CONTROL_TEXT_FORMAT = 6;@b@  public static final int FILE_STRUCTURE = 7;@b@  public static final int RECORD_STRUCTURE = 8;@b@  public static final int PAGE_STRUCTURE = 9;@b@  public static final int STREAM_TRANSFER_MODE = 10;@b@  public static final int BLOCK_TRANSFER_MODE = 11;@b@  public static final int COMPRESSED_TRANSFER_MODE = 12;@b@  public static final String DEFAULT_CONTROL_ENCODING = "ISO-8859-1";@b@  private static final String __modes = "AEILNTCFRPSBC";@b@  protected int _replyCode;@b@  protected ArrayList<String> _replyLines;@b@  protected boolean _newReplyString;@b@  protected String _replyString;@b@  protected String _controlEncoding;@b@  protected ProtocolCommandSupport _commandSupport_;@b@  protected boolean strictMultilineParsing = false;@b@  protected BufferedReader _controlInput_;@b@  protected BufferedWriter _controlOutput_;@b@@b@  public FTP()@b@  {@b@    setDefaultPort(21);@b@    this._replyLines = new ArrayList();@b@    this._newReplyString = false;@b@    this._replyString = null;@b@    this._controlEncoding = "ISO-8859-1";@b@    this._commandSupport_ = new ProtocolCommandSupport(this);@b@  }@b@@b@  private boolean __strictCheck(String line, String code)@b@  {@b@    return ((!(line.startsWith(code))) || (line.charAt(3) != ' '));@b@  }@b@@b@  private boolean __lenientCheck(String line)@b@  {@b@    return ((line.length() < 4) || (line.charAt(3) == '-') || (!(Character.isDigit(line.charAt(0)))));@b@  }@b@@b@  private void __getReply()@b@    throws IOException@b@  {@b@    __getReply(true);@b@  }@b@@b@  protected void __getReplyNoReport()@b@    throws IOException@b@  {@b@    __getReply(false);@b@  }@b@@b@  private void __getReply(boolean reportReply)@b@    throws IOException@b@  {@b@    this._newReplyString = true;@b@    this._replyLines.clear();@b@@b@    String line = this._controlInput_.readLine();@b@@b@    if (line == null) {@b@      throw new FTPConnectionClosedException("Connection closed without indication.");@b@    }@b@@b@    int length = line.length();@b@    if (length < 3) {@b@      throw new MalformedServerReplyException("Truncated server reply: " + line);@b@    }@b@@b@    String code = null;@b@    try@b@    {@b@      code = line.substring(0, 3);@b@      this._replyCode = Integer.parseInt(code);@b@    }@b@    catch (NumberFormatException e)@b@    {@b@      throw new MalformedServerReplyException("Could not parse response code.\nServer Reply: " + line);@b@    }@b@@b@    this._replyLines.add(line);@b@@b@    if ((length > 3) && (line.charAt(3) == '-')) {@b@      do@b@        while (true)@b@        {@b@          line = this._controlInput_.readLine();@b@@b@          if (line == null) {@b@            throw new FTPConnectionClosedException("Connection closed without indication.");@b@          }@b@@b@          this._replyLines.add(line);@b@@b@          if (!(isStrictMultilineParsing())) break; if (!(__strictCheck(line, code))) break label206;  }@b@      while (__lenientCheck(line));@b@    }@b@@b@    label206: fireReplyReceived(this._replyCode, getReplyString());@b@@b@    if (this._replyCode == 421)@b@      throw new FTPConnectionClosedException("FTP response 421 received.  Server closed connection.");@b@  }@b@@b@  protected void _connectAction_()@b@    throws IOException@b@  {@b@    super._connectAction_();@b@    this._controlInput_ = new CRLFLineReader(new InputStreamReader(this._input_, getControlEncoding()));@b@@b@    this._controlOutput_ = new BufferedWriter(new OutputStreamWriter(this._output_, getControlEncoding()));@b@@b@    if (this.connectTimeout > 0) {@b@      int original = this._socket_.getSoTimeout();@b@      this._socket_.setSoTimeout(this.connectTimeout);@b@      try {@b@        __getReply();@b@@b@        if (FTPReply.isPositivePreliminary(this._replyCode))@b@          __getReply();@b@      } catch (SocketTimeoutException e) {@b@        IOException ioe = new IOException("Timed out waiting for initial connect reply");@b@@b@        throw ioe;@b@      } finally {@b@        this._socket_.setSoTimeout(original);@b@      }@b@    } else {@b@      __getReply();@b@@b@      if (FTPReply.isPositivePreliminary(this._replyCode))@b@        __getReply();@b@    }@b@  }@b@@b@  public void setControlEncoding(String encoding)@b@  {@b@    this._controlEncoding = encoding;@b@  }@b@@b@  public String getControlEncoding()@b@  {@b@    return this._controlEncoding;@b@  }@b@@b@  public void disconnect()@b@    throws IOException@b@  {@b@    super.disconnect();@b@    this._controlInput_ = null;@b@    this._controlOutput_ = null;@b@    this._newReplyString = false;@b@    this._replyString = null;@b@  }@b@@b@  public int sendCommand(String command, String args)@b@    throws IOException@b@  {@b@    if (this._controlOutput_ == null) {@b@      throw new IOException("Connection is not open");@b@    }@b@@b@    String message = __buildMessage(command, args);@b@@b@    __send(message);@b@@b@    fireCommandSent(command, message);@b@@b@    __getReply();@b@    return this._replyCode;@b@  }@b@@b@  private String __buildMessage(String command, String args) {@b@    StringBuilder __commandBuffer = new StringBuilder();@b@@b@    __commandBuffer.append(command);@b@@b@    if (args != null)@b@    {@b@      __commandBuffer.append(' ');@b@      __commandBuffer.append(args);@b@    }@b@    __commandBuffer.append("\r\n");@b@    return __commandBuffer.toString();@b@  }@b@@b@  private void __send(String message) throws IOException, FTPConnectionClosedException, SocketException@b@  {@b@    try {@b@      this._controlOutput_.write(message);@b@      this._controlOutput_.flush();@b@    }@b@    catch (SocketException e)@b@    {@b@      if (!(isConnected()))@b@      {@b@        throw new FTPConnectionClosedException("Connection unexpectedly closed.");@b@      }@b@@b@      throw e;@b@    }@b@  }@b@@b@  protected void __noop()@b@    throws IOException@b@  {@b@    String msg = __buildMessage(FTPCommand.getCommand(32), null);@b@    __send(msg);@b@    __getReplyNoReport();@b@  }@b@@b@  public int sendCommand(int command, String args)@b@    throws IOException@b@  {@b@    return sendCommand(FTPCommand.getCommand(command), args);@b@  }@b@@b@  public int sendCommand(String command)@b@    throws IOException@b@  {@b@    return sendCommand(command, null);@b@  }@b@@b@  public int sendCommand(int command)@b@    throws IOException@b@  {@b@    return sendCommand(command, null);@b@  }@b@@b@  public int getReplyCode()@b@  {@b@    return this._replyCode;@b@  }@b@@b@  public int getReply()@b@    throws IOException@b@  {@b@    __getReply();@b@    return this._replyCode;@b@  }@b@@b@  public String[] getReplyStrings()@b@  {@b@    return ((String[])this._replyLines.toArray(new String[this._replyLines.size()]));@b@  }@b@@b@  public String getReplyString()@b@  {@b@    if (!(this._newReplyString)) {@b@      return this._replyString;@b@    }@b@@b@    StringBuilder buffer = new StringBuilder(256);@b@@b@    for (String line : this._replyLines) {@b@      buffer.append(line);@b@      buffer.append("\r\n");@b@    }@b@@b@    this._newReplyString = false;@b@@b@    return (this._replyString = buffer.toString());@b@  }@b@@b@  public int user(String username)@b@    throws IOException@b@  {@b@    return sendCommand(0, username);@b@  }@b@@b@  public int pass(String password)@b@    throws IOException@b@  {@b@    return sendCommand(1, password);@b@  }@b@@b@  public int acct(String account)@b@    throws IOException@b@  {@b@    return sendCommand(2, account);@b@  }@b@@b@  public int abor()@b@    throws IOException@b@  {@b@    return sendCommand(21);@b@  }@b@@b@  public int cwd(String directory)@b@    throws IOException@b@  {@b@    return sendCommand(3, directory);@b@  }@b@@b@  public int cdup()@b@    throws IOException@b@  {@b@    return sendCommand(4);@b@  }@b@@b@  public int quit()@b@    throws IOException@b@  {@b@    return sendCommand(7);@b@  }@b@@b@  public int rein()@b@    throws IOException@b@  {@b@    return sendCommand(6);@b@  }@b@@b@  public int smnt(String dir)@b@    throws IOException@b@  {@b@    return sendCommand(5, dir);@b@  }@b@@b@  public int port(InetAddress host, int port)@b@    throws IOException@b@  {@b@    StringBuilder info = new StringBuilder(24);@b@@b@    info.append(host.getHostAddress().replace('.', ','));@b@    int num = port >>> 8;@b@    info.append(',');@b@    info.append(num);@b@    info.append(',');@b@    num = port & 0xFF;@b@    info.append(num);@b@@b@    return sendCommand(8, info.toString());@b@  }@b@@b@  public int eprt(InetAddress host, int port)@b@    throws IOException@b@  {@b@    StringBuilder info = new StringBuilder();@b@@b@    String h = host.getHostAddress();@b@    int num = h.indexOf("%");@b@    if (num > 0)@b@      h = h.substring(0, num);@b@@b@    info.append("|");@b@@b@    if (host instanceof Inet4Address)@b@      info.append("1");@b@    else if (host instanceof Inet6Address)@b@      info.append("2");@b@    info.append("|");@b@    info.append(h);@b@    info.append("|");@b@    info.append(port);@b@    info.append("|");@b@@b@    return sendCommand(37, info.toString());@b@  }@b@@b@  public int pasv()@b@    throws IOException@b@  {@b@    return sendCommand(9);@b@  }@b@@b@  public int epsv()@b@    throws IOException@b@  {@b@    return sendCommand(36);@b@  }@b@@b@  public int type(int fileType, int formatOrByteSize)@b@    throws IOException@b@  {@b@    StringBuilder arg = new StringBuilder();@b@@b@    arg.append("AEILNTCFRPSBC".charAt(fileType));@b@    arg.append(' ');@b@    if (fileType == 3)@b@      arg.append(formatOrByteSize);@b@    else@b@      arg.append("AEILNTCFRPSBC".charAt(formatOrByteSize));@b@@b@    return sendCommand(10, arg.toString());@b@  }@b@@b@  public int type(int fileType)@b@    throws IOException@b@  {@b@    return sendCommand(10, "AEILNTCFRPSBC".substring(fileType, fileType + 1));@b@  }@b@@b@  public int stru(int structure)@b@    throws IOException@b@  {@b@    return sendCommand(11, "AEILNTCFRPSBC".substring(structure, structure + 1));@b@  }@b@@b@  public int mode(int mode)@b@    throws IOException@b@  {@b@    return sendCommand(12, "AEILNTCFRPSBC".substring(mode, mode + 1));@b@  }@b@@b@  public int retr(String pathname)@b@    throws IOException@b@  {@b@    return sendCommand(13, pathname);@b@  }@b@@b@  public int stor(String pathname)@b@    throws IOException@b@  {@b@    return sendCommand(14, pathname);@b@  }@b@@b@  public int stou()@b@    throws IOException@b@  {@b@    return sendCommand(15);@b@  }@b@@b@  public int stou(String pathname)@b@    throws IOException@b@  {@b@    return sendCommand(15, pathname);@b@  }@b@@b@  public int appe(String pathname)@b@    throws IOException@b@  {@b@    return sendCommand(16, pathname);@b@  }@b@@b@  public int allo(int bytes)@b@    throws IOException@b@  {@b@    return sendCommand(17, Integer.toString(bytes));@b@  }@b@@b@  public int feat()@b@    throws IOException@b@  {@b@    return sendCommand(34);@b@  }@b@@b@  public int allo(int bytes, int recordSize)@b@    throws IOException@b@  {@b@    return sendCommand(17, Integer.toString(bytes) + " R " + Integer.toString(recordSize));@b@  }@b@@b@  public int rest(String marker)@b@    throws IOException@b@  {@b@    return sendCommand(18, marker);@b@  }@b@@b@  public int mdtm(String file)@b@    throws IOException@b@  {@b@    return sendCommand(33, file);@b@  }@b@@b@  public int mfmt(String pathname, String timeval)@b@    throws IOException@b@  {@b@    return sendCommand(35, timeval + " " + pathname);@b@  }@b@@b@  public int rnfr(String pathname)@b@    throws IOException@b@  {@b@    return sendCommand(19, pathname);@b@  }@b@@b@  public int rnto(String pathname)@b@    throws IOException@b@  {@b@    return sendCommand(20, pathname);@b@  }@b@@b@  public int dele(String pathname)@b@    throws IOException@b@  {@b@    return sendCommand(22, pathname);@b@  }@b@@b@  public int rmd(String pathname)@b@    throws IOException@b@  {@b@    return sendCommand(23, pathname);@b@  }@b@@b@  public int mkd(String pathname)@b@    throws IOException@b@  {@b@    return sendCommand(24, pathname);@b@  }@b@@b@  public int pwd()@b@    throws IOException@b@  {@b@    return sendCommand(25);@b@  }@b@@b@  public int list()@b@    throws IOException@b@  {@b@    return sendCommand(26);@b@  }@b@@b@  public int list(String pathname)@b@    throws IOException@b@  {@b@    return sendCommand(26, pathname);@b@  }@b@@b@  public int mlsd()@b@    throws IOException@b@  {@b@    return sendCommand(38);@b@  }@b@@b@  public int mlsd(String path)@b@    throws IOException@b@  {@b@    return sendCommand(38, path);@b@  }@b@@b@  public int mlst()@b@    throws IOException@b@  {@b@    return sendCommand(39);@b@  }@b@@b@  public int mlst(String path)@b@    throws IOException@b@  {@b@    return sendCommand(39, path);@b@  }@b@@b@  public int nlst()@b@    throws IOException@b@  {@b@    return sendCommand(27);@b@  }@b@@b@  public int nlst(String pathname)@b@    throws IOException@b@  {@b@    return sendCommand(27, pathname);@b@  }@b@@b@  public int site(String parameters)@b@    throws IOException@b@  {@b@    return sendCommand(28, parameters);@b@  }@b@@b@  public int syst()@b@    throws IOException@b@  {@b@    return sendCommand(29);@b@  }@b@@b@  public int stat()@b@    throws IOException@b@  {@b@    return sendCommand(30);@b@  }@b@@b@  public int stat(String pathname)@b@    throws IOException@b@  {@b@    return sendCommand(30, pathname);@b@  }@b@@b@  public int help()@b@    throws IOException@b@  {@b@    return sendCommand(31);@b@  }@b@@b@  public int help(String command)@b@    throws IOException@b@  {@b@    return sendCommand(31, command);@b@  }@b@@b@  public int noop()@b@    throws IOException@b@  {@b@    return sendCommand(32);@b@  }@b@@b@  public boolean isStrictMultilineParsing()@b@  {@b@    return this.strictMultilineParsing;@b@  }@b@@b@  public void setStrictMultilineParsing(boolean strictMultilineParsing)@b@  {@b@    this.strictMultilineParsing = strictMultilineParsing;@b@  }@b@@b@  protected ProtocolCommandSupport getCommandSupport()@b@  {@b@    return this._commandSupport_;@b@  }@b@}

3.SocketClient类

package org.apache.commons.net;@b@@b@import java.io.Closeable;@b@import java.io.IOException;@b@import java.io.InputStream;@b@import java.io.OutputStream;@b@import java.net.InetAddress;@b@import java.net.InetSocketAddress;@b@import java.net.Socket;@b@import java.net.SocketException;@b@import javax.net.ServerSocketFactory;@b@import javax.net.SocketFactory;@b@@b@public abstract class SocketClient@b@{@b@  public static final String NETASCII_EOL = "\r\n";@b@  private static final SocketFactory __DEFAULT_SOCKET_FACTORY = SocketFactory.getDefault();@b@  private static final ServerSocketFactory __DEFAULT_SERVER_SOCKET_FACTORY = ServerSocketFactory.getDefault();@b@  private ProtocolCommandSupport __commandSupport;@b@  protected int _timeout_;@b@  protected Socket _socket_;@b@  protected int _defaultPort_;@b@  protected InputStream _input_;@b@  protected OutputStream _output_;@b@  protected SocketFactory _socketFactory_;@b@  protected ServerSocketFactory _serverSocketFactory_;@b@  private static final int DEFAULT_CONNECT_TIMEOUT = 0;@b@  protected int connectTimeout = 0;@b@  private int receiveBufferSize = -1;@b@  private int sendBufferSize = -1;@b@@b@  public SocketClient()@b@  {@b@    this._socket_ = null;@b@    this._input_ = null;@b@    this._output_ = null;@b@    this._timeout_ = 0;@b@    this._defaultPort_ = 0;@b@    this._socketFactory_ = __DEFAULT_SOCKET_FACTORY;@b@    this._serverSocketFactory_ = __DEFAULT_SERVER_SOCKET_FACTORY;@b@  }@b@@b@  protected void _connectAction_()@b@    throws IOException@b@  {@b@    this._socket_.setSoTimeout(this._timeout_);@b@    this._input_ = this._socket_.getInputStream();@b@    this._output_ = this._socket_.getOutputStream();@b@  }@b@@b@  public void connect(InetAddress host, int port)@b@    throws SocketException, IOException@b@  {@b@    this._socket_ = this._socketFactory_.createSocket();@b@    if (this.receiveBufferSize != -1) this._socket_.setReceiveBufferSize(this.receiveBufferSize);@b@    if (this.sendBufferSize != -1) this._socket_.setSendBufferSize(this.sendBufferSize);@b@    this._socket_.connect(new InetSocketAddress(host, port), this.connectTimeout);@b@    _connectAction_();@b@  }@b@@b@  public void connect(String hostname, int port)@b@    throws SocketException, IOException@b@  {@b@    connect(InetAddress.getByName(hostname), port);@b@  }@b@@b@  public void connect(InetAddress host, int port, InetAddress localAddr, int localPort)@b@    throws SocketException, IOException@b@  {@b@    this._socket_ = this._socketFactory_.createSocket();@b@    if (this.receiveBufferSize != -1) this._socket_.setReceiveBufferSize(this.receiveBufferSize);@b@    if (this.sendBufferSize != -1) this._socket_.setSendBufferSize(this.sendBufferSize);@b@    this._socket_.bind(new InetSocketAddress(localAddr, localPort));@b@    this._socket_.connect(new InetSocketAddress(host, port), this.connectTimeout);@b@    _connectAction_();@b@  }@b@@b@  public void connect(String hostname, int port, InetAddress localAddr, int localPort)@b@    throws SocketException, IOException@b@  {@b@    connect(InetAddress.getByName(hostname), port, localAddr, localPort);@b@  }@b@@b@  public void connect(InetAddress host)@b@    throws SocketException, IOException@b@  {@b@    connect(host, this._defaultPort_);@b@  }@b@@b@  public void connect(String hostname)@b@    throws SocketException, IOException@b@  {@b@    connect(hostname, this._defaultPort_);@b@  }@b@@b@  public void disconnect()@b@    throws IOException@b@  {@b@    closeQuietly(this._socket_);@b@    closeQuietly(this._input_);@b@    closeQuietly(this._output_);@b@    this._socket_ = null;@b@    this._input_ = null;@b@    this._output_ = null;@b@  }@b@@b@  private void closeQuietly(Socket socket) {@b@    if (socket != null)@b@      try {@b@        socket.close();@b@      }@b@      catch (IOException e) {@b@      }@b@  }@b@@b@  private void closeQuietly(Closeable close) {@b@    if (close != null)@b@      try {@b@        close.close();@b@      }@b@      catch (IOException e)@b@      {@b@      }@b@  }@b@@b@  public boolean isConnected()@b@  {@b@    if (this._socket_ == null)@b@      return false;@b@@b@    return this._socket_.isConnected();@b@  }@b@@b@  public boolean isAvailable()@b@  {@b@    if (isConnected())@b@    {@b@      try {@b@        if (this._socket_.getInetAddress() == null) return false;@b@        if (this._socket_.getPort() == 0) return false;@b@        if (this._socket_.getRemoteSocketAddress() == null) return false;@b@        if (this._socket_.isClosed()) { return false;@b@        }@b@@b@        if (this._socket_.isInputShutdown()) return false;@b@        if (this._socket_.isOutputShutdown()) return false;@b@@b@        this._socket_.getInputStream();@b@        this._socket_.getOutputStream();@b@      }@b@      catch (IOException ioex)@b@      {@b@        return false;@b@      }@b@      return true;@b@    }@b@    return false;@b@  }@b@@b@  public void setDefaultPort(int port)@b@  {@b@    this._defaultPort_ = port;@b@  }@b@@b@  public int getDefaultPort()@b@  {@b@    return this._defaultPort_;@b@  }@b@@b@  public void setDefaultTimeout(int timeout)@b@  {@b@    this._timeout_ = timeout;@b@  }@b@@b@  public int getDefaultTimeout()@b@  {@b@    return this._timeout_;@b@  }@b@@b@  public void setSoTimeout(int timeout)@b@    throws SocketException@b@  {@b@    this._socket_.setSoTimeout(timeout);@b@  }@b@@b@  public void setSendBufferSize(int size)@b@    throws SocketException@b@  {@b@    this.sendBufferSize = size;@b@  }@b@@b@  protected int getSendBufferSize()@b@  {@b@    return this.sendBufferSize;@b@  }@b@@b@  public void setReceiveBufferSize(int size)@b@    throws SocketException@b@  {@b@    this.receiveBufferSize = size;@b@  }@b@@b@  protected int getReceiveBufferSize()@b@  {@b@    return this.receiveBufferSize;@b@  }@b@@b@  public int getSoTimeout()@b@    throws SocketException@b@  {@b@    return this._socket_.getSoTimeout();@b@  }@b@@b@  public void setTcpNoDelay(boolean on)@b@    throws SocketException@b@  {@b@    this._socket_.setTcpNoDelay(on);@b@  }@b@@b@  public boolean getTcpNoDelay()@b@    throws SocketException@b@  {@b@    return this._socket_.getTcpNoDelay();@b@  }@b@@b@  public void setKeepAlive(boolean keepAlive)@b@    throws SocketException@b@  {@b@    this._socket_.setKeepAlive(keepAlive);@b@  }@b@@b@  public boolean getKeepAlive()@b@    throws SocketException@b@  {@b@    return this._socket_.getKeepAlive();@b@  }@b@@b@  public void setSoLinger(boolean on, int val)@b@    throws SocketException@b@  {@b@    this._socket_.setSoLinger(on, val);@b@  }@b@@b@  public int getSoLinger()@b@    throws SocketException@b@  {@b@    return this._socket_.getSoLinger();@b@  }@b@@b@  public int getLocalPort()@b@  {@b@    return this._socket_.getLocalPort();@b@  }@b@@b@  public InetAddress getLocalAddress()@b@  {@b@    return this._socket_.getLocalAddress();@b@  }@b@@b@  public int getRemotePort()@b@  {@b@    return this._socket_.getPort();@b@  }@b@@b@  public InetAddress getRemoteAddress()@b@  {@b@    return this._socket_.getInetAddress();@b@  }@b@@b@  public boolean verifyRemote(Socket socket)@b@  {@b@    InetAddress host1 = socket.getInetAddress();@b@    InetAddress host2 = getRemoteAddress();@b@@b@    return host1.equals(host2);@b@  }@b@@b@  public void setSocketFactory(SocketFactory factory)@b@  {@b@    if (factory == null)@b@      this._socketFactory_ = __DEFAULT_SOCKET_FACTORY;@b@    else@b@      this._socketFactory_ = factory;@b@  }@b@@b@  public void setServerSocketFactory(ServerSocketFactory factory)@b@  {@b@    if (factory == null)@b@      this._serverSocketFactory_ = __DEFAULT_SERVER_SOCKET_FACTORY;@b@    else@b@      this._serverSocketFactory_ = factory;@b@  }@b@@b@  public void setConnectTimeout(int connectTimeout)@b@  {@b@    this.connectTimeout = connectTimeout;@b@  }@b@@b@  public int getConnectTimeout()@b@  {@b@    return this.connectTimeout;@b@  }@b@@b@  public ServerSocketFactory getServerSocketFactory()@b@  {@b@    return this._serverSocketFactory_;@b@  }@b@@b@  public void addProtocolCommandListener(ProtocolCommandListener listener)@b@  {@b@    getCommandSupport().addProtocolCommandListener(listener);@b@  }@b@@b@  public void removeProtocolCommandListener(ProtocolCommandListener listener)@b@  {@b@    getCommandSupport().removeProtocolCommandListener(listener);@b@  }@b@@b@  protected void fireReplyReceived(int replyCode, String reply)@b@  {@b@    if (getCommandSupport().getListenerCount() > 0)@b@      getCommandSupport().fireReplyReceived(replyCode, reply);@b@  }@b@@b@  protected void fireCommandSent(String command, String message)@b@  {@b@    if (getCommandSupport().getListenerCount() > 0)@b@      getCommandSupport().fireCommandSent(command, message);@b@  }@b@@b@  protected void createCommandSupport()@b@  {@b@    this.__commandSupport = new ProtocolCommandSupport(this);@b@  }@b@@b@  protected ProtocolCommandSupport getCommandSupport()@b@  {@b@    return this.__commandSupport;@b@  }@b@}