我们以读取NASA降水数据为例:
package ftp.ftp5;
import org.apache.commons.net.ftp.FTPClient;
import java.io.*;
public class Demo {
public static void main (String args []) throws IOException {
// 标准登陆过程
FtpClient f = new FtpClient("198.118.195.100"); //自动连接
//System.out.print("连接响应:"+f.getResponseString());
f.login("你的用户账号","你的用户账号");
f.pwd();
f.setPassive(true);
// 使用列表
//System.out.println("14行:Demo of nlist() function");
f.ascii(); // 把客户端设为ASCII模式以获取文本列表
f.cd("gpmdata/2005/05/05/1B");
BufferedReader t = f.nlist();
while( true ) {
String stringBuffer = t.readLine();
if( stringBuffer == null ) {
break;
} else{
System.out.println("23行,"+stringBuffer);
}
}
t.close();
f.closeServer();
}
}
提示:
1、读取NASA之前需要注册一个账号,默认密码也是你的账号;
2、NASA降水ftp://arthurhou.pps.eosdis.nasa.gov/对应的IP是198.118.195.100 ;
package ftp.ftp5;
import java.net.*;
import java.io.*;
import java.util.*;
public class FtpClient {
static final boolean debug = false;
public static final int FTP_PORT = 21; // ftp的端口
static int FTP_SUCCESS = 1;
static int FTP_TRY_AGAIN = 2;
static int FTP_ERROR = 3;
// 数据传输套接字
private Socket dataSocket = null;
private boolean replyPending = false;
private boolean binaryMode = false; //用HTML 和文本编写的文件必须用ASCII模式上传,BINARY模式用来传送可执行文件,压缩文件,和图片文件。
private boolean passiveMode = false; //被动模式
String user = null; // 登录用的用户名
String password = null; // 登录用的密码
String command; // 最近一次命令
int lastReplyCode; // 最近的响应信息
public String welcomeMsg; // 服务器的欢迎信息
// 从服务器返回的响应字符串对象
protected Vector serverResponse = new Vector(1);
protected Socket serverSocket = null; // 与服务器通信的套接字
public PrintWriter serverOutput; //向服务器发送命令的输出流
public InputStream serverInput; // 从服务器读取响应的缓冲流
/** 返回服务器连接的状态 */
public boolean serverIsOpen() {
return serverSocket != null;
}
/** 设置为被动模式 */
public void setPassive(boolean mode) {
passiveMode = mode;
}
/** 读取服务器的响应信息 */
public int readServerResponse() throws IOException {
StringBuffer replyBuf = new StringBuffer(32);
int c;
int continuingCode = -1;
int code = -1;
String response;
if (debug) System.out.println("readServerResponse start");
try{
while (true) {
if (debug) System.out.println("readServerResponse outer while loop: "+ serverInput.available());
while ((c = serverInput.read()) != -1) {
if (c == '\r') {
if ((c = serverInput.read()) != '\n')
replyBuf.append('\r');
}
replyBuf.append((char)c);
if (c == '\n')
break;
}
if (debug) System.out.println("Now past inner while loop");
response = replyBuf.toString();
replyBuf.setLength(0);
if (debug) {
System.out.print(response);
}
try {
code = Integer.parseInt(response.substring(0, 3));
} catch (NumberFormatException e) {
code = -1;
} catch (StringIndexOutOfBoundsException e) {
// 此行不存在响应码,循环跳到下一次
continue;
}
serverResponse.addElement(response);
if (continuingCode != -1) {
/* we've seen a XXX- sequence */
if (code != continuingCode ||
(response.length() >= 4 && response.charAt(3) == '-')) {
continue;
} else {
continuingCode = -1; // 到达程序的结尾
break;
}
} else if (response.length() >= 4 && response.charAt(3) == '-') {
continuingCode = code;
continue;
} else {
break;
}
}
}catch(Exception e){e.printStackTrace();}
if (debug) System.out.println("readServerResponse done");
return lastReplyCode = code;
}
/** 发送命令cmd给服务器 */
public void sendServer(String cmd) {
if (debug) System.out.println("sendServer start");
serverOutput.println(cmd);
if (debug) System.out.println("sendServer done");
}
/** 返回服务器的所有响应字符串 */
public String getResponseString() {
String s = new String();
for(int i = 0;i < serverResponse.size();i++) {
s+=serverResponse.elementAt(i);
}
serverResponse = new Vector(1);
return s;
}
/** 获取响应字符串 */
public String getResponseStringNoReset() {
String s = new String();
for(int i = 0;i < serverResponse.size();i++) {
s+=serverResponse.elementAt(i);
}
return s;
}
/** 发送 QUIT 命令给服务器并关闭连接 */
public void closeServer() throws IOException {
if (serverIsOpen())
{
issueCommand("QUIT");
if (! serverIsOpen())
{
return;
}
serverSocket.close();
serverSocket = null;
serverInput = null;
serverOutput = null;
}
}
protected int issueCommand(String cmd) throws IOException {
command = cmd;
int reply;
if (debug) System.out.println(cmd);
if (replyPending) {
if (debug) System.out.println("replyPending");
if (readReply() == FTP_ERROR)
System.out.print("Error reading pending reply\n");
}
replyPending = false;
do {
sendServer(cmd);
reply = readReply();
if (debug) System.out.println("in while loop of issueCommand method");
} while (reply == FTP_TRY_AGAIN);
return reply;
}
// 检测命令
protected void issueCommandCheck(String cmd) throws IOException {
if (debug) System.out.println("issueCommandCheck");
if (issueCommand(cmd) != FTP_SUCCESS) {
throw new FtpProtocolException(cmd);
}
}
/** 读取返回数据 */
protected int readReply() throws IOException {
lastReplyCode = readServerResponse();
switch (lastReplyCode / 100) {
case 1:
replyPending = true;
case 2:// 这个case用来以后扩展功能
case 3:
return FTP_SUCCESS;
case 5:
if (lastReplyCode == 530) {
if (user == null) {
throw new FtpLoginException("Not logged in");
}
return FTP_ERROR;
}
if (lastReplyCode == 550) {
if (!command.startsWith("PASS"))
throw new FileNotFoundException(command);
else
throw new FtpLoginException("Error: Wrong Password!");
}
}
return FTP_ERROR;
}
// 打开数据连接
protected Socket openDataConnection(String cmd) throws IOException {
ServerSocket portSocket = null;
String portCmd;
InetAddress myAddress = InetAddress.getLocalHost();
byte addr[] = myAddress.getAddress();
int shift;
String ipaddress;
int port = 0;
IOException e;
if (this.passiveMode) {
// 首先尝试被动模式传输
try {
getResponseString();
if (issueCommand("PASV") == FTP_ERROR) {
e = new FtpProtocolException("PASV");
throw e;
}
String reply = getResponseStringNoReset();
reply = reply.substring(reply.lastIndexOf("(") + 1, reply
.lastIndexOf(")"));
StringTokenizer st = new StringTokenizer(reply, ",");
String[] nums = new String[6];
int i = 0;
while (st.hasMoreElements()) {
try {
nums[i] = st.nextToken();
i++;
} catch (Exception a) {
a.printStackTrace();
}
}
ipaddress = nums[0] + "." + nums[1] + "." + nums[2] + "."
+ nums[3];
try {
int firstbits = Integer.parseInt(nums[4]) << 8;
int lastbits = Integer.parseInt(nums[5]);
port = firstbits + lastbits;
} catch (Exception b) {
b.printStackTrace();
}
if ((ipaddress != null) && (port != 0)) {
dataSocket = new Socket(ipaddress, port);
} else {
e = new FtpProtocolException("PASV");
throw e;
}
if (issueCommand(cmd) == FTP_ERROR) {
e = new FtpProtocolException(cmd);
throw e;
}
} catch (FtpProtocolException fpe) {
portCmd = "PORT ";
// 附加host地址
for (int i = 0; i < addr.length; i++) {
portCmd = portCmd + (addr[i] & 0xFF) + ",";
}
try {
portSocket = new ServerSocket(20000);
// 附加端口
portCmd = portCmd
+ ((portSocket.getLocalPort() >>> 8) & 0xff) + ","
+ (portSocket.getLocalPort() & 0xff);
if (issueCommand(portCmd) == FTP_ERROR) {
e = new FtpProtocolException("PORT");
throw e;
}
if (issueCommand(cmd) == FTP_ERROR) {
e = new FtpProtocolException(cmd);
throw e;
}
dataSocket = portSocket.accept();
} finally {
if (portSocket != null)
portSocket.close();
}
dataSocket = portSocket.accept();
portSocket.close();
}
}
else { // 端口传送
portCmd = "PORT ";
// 附加host地址
for (int i = 0; i < addr.length; i++) {
portCmd = portCmd + (addr[i] & 0xFF) + ",";
}
try {
portSocket = new ServerSocket(20000);
// 附加端口号
portCmd = portCmd + ((portSocket.getLocalPort() >>> 8) & 0xff)
+ "," + (portSocket.getLocalPort() & 0xff);
if (issueCommand(portCmd) == FTP_ERROR) {
e = new FtpProtocolException("PORT");
throw e;
}
if (issueCommand(cmd) == FTP_ERROR) {
e = new FtpProtocolException(cmd);
throw e;
}
dataSocket = portSocket.accept();
} finally {
if (portSocket != null)
portSocket.close();
}
dataSocket = portSocket.accept();
portSocket.close();
}
return dataSocket;
}
/** 打开一个到host的FTP连接 */
public void openServer(String host) throws IOException, UnknownHostException {
int port = FTP_PORT;
if (serverSocket != null)
closeServer();
serverSocket = new Socket(host, FTP_PORT);
serverOutput = new PrintWriter(new BufferedOutputStream(serverSocket.getOutputStream()),true);
serverInput = new BufferedInputStream(serverSocket.getInputStream());
}
/** 打开到 host端口为port的FTP连接 */
public void openServer(String host, int port) throws IOException, UnknownHostException {
if (serverSocket != null){
closeServer();
}
try{
serverSocket = new Socket(host, port);
serverOutput = new PrintWriter(new BufferedOutputStream(serverSocket.getOutputStream()),true);
serverInput = new BufferedInputStream(serverSocket.getInputStream());
if (readReply() == FTP_ERROR){
throw new FtpConnectException("Welcome message");
}
}catch (Exception e){
e.printStackTrace();
}
}
/** 使用用户名user和密码password登录*/
public void login(String user, String password) throws IOException {
if (!serverIsOpen()){
throw new FtpLoginException("Error: not connected to host.\n");
}
this.user = user;
this.password = password;
if (issueCommand("USER " + user) == FTP_ERROR)
throw new FtpLoginException("Error: User not found.\n");
if (password != null && issueCommand("PASS " + password) == FTP_ERROR)
throw new FtpLoginException("Error: Wrong Password.\n");
}
/** 只用用户名user不用密码登录 */
public void login(String user) throws IOException {
if (!serverIsOpen())
throw new FtpLoginException("not connected to host");
this.user = user;
if (issueCommand("USER " + user) == FTP_ERROR)
throw new FtpLoginException("Error: Invalid Username.\n");
}
/** 以Ascii 模式从FTP server获取一个文件 */
public BufferedReader getAscii(String filename) throws IOException {
Socket s = null;
try {
s = openDataConnection("RETR " + filename);
} catch (FileNotFoundException fileException) {fileException.printStackTrace();}
return new BufferedReader( new InputStreamReader(s.getInputStream()));
}
/** 以Binary 模式从FTP server获取一个文件 */
public BufferedInputStream getBinary(String filename) throws IOException {
Socket s = null;
try {
s = openDataConnection("RETR " + filename);
} catch (FileNotFoundException fileException) {fileException.printStackTrace();}
return new BufferedInputStream(s.getInputStream());
}
/** 以Ascii 模式发送一个文件 */
public BufferedWriter putAscii(String filename) throws IOException {
Socket s = openDataConnection("STOR " + filename);
return new BufferedWriter(new OutputStreamWriter(s.getOutputStream()),4096);
}
/** 以Binary 模式向server发送一个文件 */
public BufferedOutputStream putBinary(String filename) throws IOException {
Socket s = openDataConnection("STOR " + filename);
return new BufferedOutputStream(s.getOutputStream());
}
/** 以Ascii 模式在server上创建或添加一个文件 */
public BufferedWriter appendAscii(String filename) throws IOException {
Socket s = openDataConnection("APPE " + filename);
return new BufferedWriter(new OutputStreamWriter(s.getOutputStream()),4096);
}
/** 以Binary 模式在server上创建或添加一个文件 */
public BufferedOutputStream appendBinary(String filename) throws IOException {
Socket s = openDataConnection("APPE " + filename);
return new BufferedOutputStream(s.getOutputStream());
}
/** NLIST 文件在远端 FTP server */
public BufferedReader nlist() throws IOException {
Socket s = openDataConnection("NLST");
return new BufferedReader( new InputStreamReader(s.getInputStream()));
}
/** LIST files 在远端 FTP server */
public BufferedReader list() throws IOException {
Socket s = openDataConnection("LIST");
return new BufferedReader( new InputStreamReader(s.getInputStream()));
}
/** 在FTP server上改变文件路径 */
public void cd(String remoteDirectory) throws IOException {
issueCommandCheck("CWD " + remoteDirectory);
}
/** 在server上改变文件名 */
public void rename(String oldFile, String newFile) throws IOException {
issueCommandCheck("RNFR " + oldFile);
issueCommandCheck("RNTO " + newFile);
}
/** Site 命令 */
public void site(String params) throws IOException {
issueCommandCheck("SITE "+ params);
}
/** 设置为'I'传输模式 */
public void binary() throws IOException {
issueCommandCheck("TYPE I");
binaryMode = true;
}
/** 设置为'A'传输模式 */
public void ascii() throws IOException {
issueCommandCheck("TYPE A");
binaryMode = false;
}
/** 发送Abort 命令 */
public void abort() throws IOException {
issueCommandCheck("ABOR");
}
/** 在远端系统浏览上一级目录 */
public void cdup() throws IOException {
issueCommandCheck("CDUP");
}
/** 在远端系统中创建一个目录 */
public void mkdir(String s) throws IOException {
issueCommandCheck("MKD " + s);
}
/** 在远端系统中删除某个路径 */
public void rmdir(String s) throws IOException {
issueCommandCheck("RMD " + s);
}
/** 删除文件 */
public void delete(String s) throws IOException {
issueCommandCheck("DELE " + s);
}
/** 获取当前目录名 */
public void pwd() throws IOException {
issueCommandCheck("PWD");
}
/** 获取远端系统的信息 */
public void syst() throws IOException {
issueCommandCheck("SYST");
}
/** 新的FTP客户端连接到host <i>host</i>. */
public FtpClient(String host) throws IOException {
openServer(host, FTP_PORT);
}
/** 新的FTP客户端连接到host <i>host</i>, port <i>port</i>. */
public FtpClient(String host, int port) throws IOException {
openServer(host, port);
}
}
下面是异常类:
class FtpLoginException extends FtpProtocolException {
FtpLoginException(String s) {
super(s);
}
}
class FtpConnectException extends FtpProtocolException {
FtpConnectException(String s) {
super(s);
}
}
class FtpProtocolException extends IOException {
FtpProtocolException(String s) {
super(s);
}
}
运行结果: