⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftpclient.java

📁 具有不同语法高亮的编辑器实例
💻 JAVA
字号:
package org.fife.net.ftp;

import java.io.*;
import java.net.*;
import java.util.*;

import org.fife.net.TelnetInputStream;
//import org.fife.net.TelnetOutputStream;


/**
 * A very basic FTP client.
 *
 * @author Robert Futrell
 * @version 0.5
 */
public class FTPClient {

	private static final int TYPE_MIN			= 0;
	public static final int TYPE_ASCII			= 0;
	public static final int TYPE_IMAGE			= 1;
	public static final int TYPE_EBCDIC		= 2;
	private static final int TYPE_MAX			= 2;

	private String host;
	private int port;
	private boolean connected;

	private Socket socket;
	private BufferedInputStream inputStream;
	private PrintStream outputStream;
	private String lastReply;
	private boolean replyPending;
	private boolean binary;

	private static final int DEFAULT_PORT	= 21;


/*****************************************************************************/


	/**
	 * Constructor.
	 */
	public FTPClient() {
		replyPending = false;
		binary = false;
	}


/*****************************************************************************/


	/**
	 * Changes to the specified directory on the remote FTP server.
	 *
	 * @param toDir The directory into which to move.
	 * @return Whether the command was successful.  If this client isn't
	 *         connected to an FTP server, <code>false</code> is returned.
	 * @throws IOException If an I/O error occurs.
	 */
	public boolean cd(String toDir) throws IOException {
		if (!isConnected())
			return false;
		return !isErrorReply(issueCommand("CWD " + toDir));
	}


/*****************************************************************************/


	/**
	 * Opens a connection to an FTP server on the specified host.  The FTP
	 * server is assumed to be on port 21.
	 *
	 * @param host The host to connect to.
	 * @throws IOException If an I/O exception occurs.
	 * @see #connect(String host, int port)
	 * @see #disconnect
	 */
	public void connect(String host) throws IOException {
		connect(host, DEFAULT_PORT);
	}


/*****************************************************************************/


	/**
	 * Opens a connection to an FTP server on the specified host at the
	 * specified port.
	 *
	 * @param host The host to connect to.
	 * @param port The port on which the FTP server is running.
	 * @throws IOException If an I/O error occurs.
	 * @see #connect(String host)
	 * @see #disconnect
	 */
	public void connect(String host, int port) throws IOException {
		this.host = host;
		this.port = port;
		if (isConnected())
			disconnect();
		socket = new Socket();
		socket.connect(new InetSocketAddress(host, port));
		outputStream = new PrintStream(new BufferedOutputStream(
									socket.getOutputStream()), true);
		inputStream = new BufferedInputStream(socket.getInputStream());
		getReply(); // Get possible 220 msg about FTP server.
		connected = true;
	}


/*****************************************************************************/


	/**
	 * Creates and returns a socket for the specified command.
	 *
	 * @param command The command.
	 * @return The socket.
	 * @throws IOException If an I/O error occurs.
	 */
	private Socket createSocketForCommand(String command) throws IOException {
		ServerSocket s = new ServerSocket(0, 1);
		Socket clientSocket = null;
		try {
			InetAddress address = s.getInetAddress();
			if (address.isAnyLocalAddress())
				address = socket.getLocalAddress();
			String command2 = "PORT ";
			byte[] addr = address.getAddress();
			for (int i = 0; i < addr.length; i++)
				command2 += (addr[i] & 0xFF) + ",";
			command2 += ((s.getLocalPort() >>> 8) & 0xff) + ","
							+ (s.getLocalPort() & 0xff);
			int code = issueCommand(command2);
			if (isErrorReply(code)) {
				throw new IOException("PORT: " + getLastReply());
			}
			code = issueCommand(command);
			if (isErrorReply(code)) {
				throw new IOException(command + ":" + getLastReply());
			}
			clientSocket = s.accept();
		} finally {
			s.close();
		}
		return clientSocket;
	}


/*****************************************************************************/


	/**
	 * Deletes a file on the FTP server.
	 *
	 * @param fileName The file to delete.
	 * @return Whether the delete was successful.  If this client is not
	 *         connected to an FTP server, <code>false</code> is returned.
	 * @throws IOException If an I/O error occurs.
	 * @see #rmd
	 */
	public boolean dele(String fileName) throws IOException {
		if (!isConnected())
			return false;
		return !isErrorReply(issueCommand("DELE " + fileName));
	}

	
/*****************************************************************************/


	/**
	 * Closes the current FTP connection by issuing a <code>QUIT</code>
	 * command.
	 *
	 * @throws IOException If an I/O error occurs.
	 * @see #connect(String host)
	 * @see #connect(String host, int port)
	 */
	public void disconnect() throws IOException {
		issueCommand("QUIT");
		socket.close();
		inputStream = null;
		outputStream = null;
		connected = false;
	}


/*****************************************************************************/


	/**
	 * Returns an input stream for the specified file on the FTP server.
	 * If this client is not connected to an FTP server, <code>null</code>
	 * is returned.
	 *
	 * @param fileName The file to retrieve.
	 * @return An input stream for the file.
	 * @throws IOException If an I/O error occurs.
	 * @see #put
	 */
	public TelnetInputStream get(String fileName) throws IOException {
		if (!isConnected())
			return null;
		Socket s = createSocketForCommand("RETR " + fileName);
		return new TelnetInputStream(s.getInputStream(), isBinary());
	}


/*****************************************************************************/


	/**
	 * Returns the reply from the FTP server from the last action, as a
	 * string.
	 *
	 * @return The last reply received from the FTP server.
	 */
	public String getLastReply() {
		return lastReply;
	}


/*****************************************************************************/


	/**
	 * Gets the reply from the server from a command.
	 *
	 * @return
	 * @throws IOException If an I/O error occurs.
	 */
	private int getReply() throws IOException {

		int ch;
		int code;
		int codeToMatch = -1;
		StringBuffer buf = new StringBuffer(80);
		lastReply = "";

		while (true) {
			while ((ch=inputStream.read()) != -1) {
				if (ch=='\r') {
					if ((ch=inputStream.read()) != '\n')
						buf.append('\r');
				}
				buf.append((char)ch);
				if (ch=='\n')
					break;
			}
			String reply = buf.toString();
			buf.setLength(0);
			lastReply += reply;
			int length = reply.length();
			if (length==0)
				code = -1;
			else if (length<3)
				continue; // Need at least 3-digit reply code.
			try {
				code = Integer.parseInt(reply.substring(0,3));
			} catch (NumberFormatException nfe) {
				code = -1; // Should never happen.
			}
			if (codeToMatch!=-1) {
				if (code!=codeToMatch ||
						(length>3 && reply.charAt(3)=='-'))
					continue;
				break; // code==codeToMatch; no '-' => we're done.
			}
			else if (length>3 && reply.charAt(3)=='-') {
				codeToMatch = code;
				continue;
			}
			else
				break;
		} // End of while (true).

		return code;

	}


/*****************************************************************************/


	/**
	 * Returns whether this FTP session is currently sending/receiving files
	 * in binary mode.
	 *
	 * @return Whether files are being transfered in binary mode.
	 * @see #type
	 */
	public boolean isBinary() {
		return binary;
	}


/*****************************************************************************/


	/**
	 * Returns whether this client is connected to an FTP server.  If it is
	 * not, then all attempted FTP operations (login, sending and receiving
	 * files, etc.) will fail.
	 *
	 * @return Whether this client is connected to an FTP server.
	 * @see #connect(String host)
	 * @see #connect(String host, int port)
	 */
	public boolean isConnected() {
		return connected;
	}


/*****************************************************************************/


	/**
	 * Returns whether the specified FTP reply code represents an error.
	 *
	 * @return Whether the reply code represents an error.
	 */
	private static final boolean isErrorReply(int code) {
		return (code/100)>=4;//==5;
	}


/*****************************************************************************/


	/**
	 * Returns whether the specified FTP reply code represents a "command
	 * in progress; real reply code coming later" message.
	 *
	 * @return Whether the specified reply code is a preliminary reply code.
	 */
	private static final boolean isPreliminaryReply(int code) {
		return (code/100)==1;
	}


/*****************************************************************************/


	/**
	 * Issues an FTP command to the FtP server.
	 *
	 * @param command The command to issue.
	 * @return The 3-digit reply code corresponding to the response
	 *         received from the server.
	 * @throws IOException If an I/O error occurs.
	 */
	private int issueCommand(String command) throws IOException {
		int code;
		while (replyPending) {
			code = getReply();
			replyPending = isPreliminaryReply(code);
		}
		outputStream.print(command + "\r\n");
		code = getReply();
		replyPending = isPreliminaryReply(code);
		return code;
	}


/*****************************************************************************/


	/**
	 * Logs in to the FTP server as the specified user.  If this FTP client
	 * is not connected to an FTP server, this method simply returns
	 * <code>false</code>.
	 *
	 * @param userID The user to log in as.
	 * @param password The password for the user.
	 * @return Whether the login was successful.
	 * @throws IOException If an I/O error occurs.
	 */
	public boolean login(String userID, String password) throws IOException {
		if (isConnected()) {
			int code = issueCommand("USER " + userID);
			if (isErrorReply(code))
				return false;
			if (code==331) {
				code = issueCommand("PASS " + password);
				if (isErrorReply(code))
					return false;
			}
			return true;
		}
		return false;
	}


/*****************************************************************************/


	/**
	 * Performs an "ls" command on the FTP server and returns its output.
	 *
	 * @return The result of the "ls" command.
	 * @throws IOException If an I/O error occurs.
	 */
	public TelnetInputStream ls() throws IOException {
		return ls(".");
	}


/*****************************************************************************/


	/**
	 * Performs an "ls" command on the FTP server for the specified directory
	 * and returns its output.  If this client is not connected to an FTP
	 * server or an error occurs, <code>null</code> is returned.
	 *
	 * @return The result of the "ls" command.
	 * @throws IOException If an I/O error occurs.
	 */
	public TelnetInputStream ls(String dir) throws IOException {
		if (!isConnected())
			return null;
		Socket s = createSocketForCommand("LIST " + dir);
		return new TelnetInputStream(s.getInputStream(), isBinary());
	}


/*****************************************************************************/


	/**
	 * Returns the current working directory of the FTP client.  If this
	 * client isn't connected to an FTP server or an error occurs,
	 * <code>null</code> is returned.
	 *
	 * @return The current working directory.
	 * @throws IOException If an I/O error occurs.
	 */
	public String pwd() throws IOException {
		if (!isConnected())
			return null;
		if (isErrorReply(issueCommand("PWD")))
			return null;
		return getLastReply(); // FIXME:  Just grab directory, not full line!
	}


/*****************************************************************************/


	/**
	 * Removes a directory from an FTP server.
	 *
	 * @param dir The name of the directory to remove.
	 * @return Whether the directory was successfully removed.  If this client
	 *         is not connected to an FTP server, <code>false</code> is
	 *         returned.
	 * @throws IOException If an I/O error occurs.
	 * @see #dele
	 */
	public boolean rmd(String dir) throws IOException {
		if (!isConnected())
			return false;
		return !isErrorReply(issueCommand("RMD " + dir));
	}


/*****************************************************************************/


	/**
	 * Sets the type used in file transfer (e.g., "ASCII" or "IMAGE").
	 *
	 * @param type The type to use.
	 * @return Whether the command was successful.
	 * @throws IllegalArgumentException If <code>type</code> is not valid.
	 * @throws IOException If an I/O error occurs.
	 */
	public boolean type(int type) throws IOException {
		if (type<TYPE_MIN || type>TYPE_MAX)
			throw new IllegalArgumentException("Invalid type: " + type);
		if (!isConnected())
			return false;
		String command = "TYPE ";
		switch (type) {
			case TYPE_ASCII:
				command += "A";
				break;
			case TYPE_IMAGE:
				command += "I";
				break;
			case TYPE_EBCDIC:
				command += "E";
				break;
		}
		boolean rc = !isErrorReply(issueCommand(command));
		binary = (type==TYPE_IMAGE && rc);
		return rc;
	}


/*****************************************************************************/

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -