整合工具包,写FTP的实现,出现了问题,解决如下
apach自带的FTPExample的类
- /***略掉了包和 import的说明部分***/
- 043 public final class FTPExample
- 044 {
- 045
- 046 public static final String USAGE =
- 047 "Usage: ftp [-s] [-b] <hostname> <username> <password> <remote file> <local file>/n" +
- 048 "/nDefault behavior is to download a file and use ASCII transfer mode./n" +
- 049 "/t-s store file on server (upload)/n" +
- 050 "/t-b use binary transfer mode/n" ;
- 051
- 052 public static final void main(String[] args)
- 053 {
- 054 int base = 0 ;
- 055 boolean storeFile = false , binaryTransfer = false , error = false ;
- 056 String server, username, password, remote, local;
- 057 FTPClient ftp ;
- 058
- 059 for (base = 0 ; base < args.length; base++)
- 060 {
- 061 if (args[base].startsWith("-s" ))
- 062 storeFile = true ;
- 063 else if (args[base].startsWith("-b" ))
- 064 binaryTransfer = true ;
- 065 else
- 066 break ;
- 067 }
- 068
- 069 if ((args.length - base) != 5 )
- 070 {
- 071 System.err.println(USAGE);
- 072 System.exit(1 );
- 073 }
- 074
- 075 server = args[base++];
- 076 username = args[base++];
- 077 password = args[base++];
- 078 remote = args[base++];
- 079 local = args[base];
- 080
- 081 ftp = new FTPClient();
- 082 ftp .addProtocolCommandListener(new PrintCommandListener(
- 083 new PrintWriter(System.out)));
- 084
- 085 try
- 086 {
- 087 int reply;
- 088 ftp .connect(server);
- 089 System.out.println("Connected to " + server + "." );
- 090
- 091 // After connection attempt, you should check the reply code to verify
- 092 // success.
- 093 reply = ftp .getReplyCode();
- 094
- 095 if (!FTPReply.isPositiveCompletion(reply))
- 096 {
- 097 ftp .disconnect();
- 098 System.err.println("FTP server refused connection." );
- 099 System.exit(1 );
- 100 }
- 101 }
- 102 catch (IOException e)
- 103 {
- 104 if (ftp .isConnected())
- 105 {
- 106 try
- 107 {
- 108 ftp .disconnect();
- 109 }
- 110 catch (IOException f)
- 111 {
- 112 // do nothing
- 113 }
- 114 }
- 115 System.err.println("Could not connect to server." );
- 116 e.printStackTrace();
- 117 System.exit(1 );
- 118 }
- 119
- 120 __main:
- 121 try
- 122 {
- 123 if (!ftp .login(username, password))
- 124 {
- 125 ftp .logout();
- 126 error = true ;
- 127 break __main;
- 128 }
- 129
- 130 System.out.println("Remote system is " + ftp .getSystemName());
- 131
- 132 if (binaryTransfer)
- 133 ftp .setFileType(FTP .BINARY_FILE_TYPE);
- 134
- 135 // Use passive mode as default because most of us are
- 136 // behind firewalls these days.
- 137 ftp .enterLocalPassiveMode();
- 138
- 139 if (storeFile )
- 140 {
- 141 InputStream input;
- 142
- 143 input = new FileInputStream(local);
- 144
- 145 ftp .storeFile (remote, input);
- 146
- 147 input.close();
- 148 }
- 149 else
- 150 {
- 151 OutputStream output;
- 152
- 153 output = new FileOutputStream(local);
- 154
- 155 ftp .retrieveFile(remote, output);
- 156
- 157 output.close();
- 158 }
- 159
- 160 ftp .logout();
- 161 }
- 162 catch (FTPConnectionClosedException e)
- 163 {
- 164 error = true ;
- 165 System.err.println("Server closed connection." );
- 166 e.printStackTrace();
- 167 }
- 168 catch (IOException e)
- 169 {
- 170 error = true ;
- 171 e.printStackTrace();
- 172 }
- 173 finally
- 174 {
- 175 if (ftp .isConnected())
- 176 {
- 177 try
- 178 {
- 179 ftp .disconnect();
- 180 }
- 181 catch (IOException f)
- 182 {
- 183 // do nothing
- 184 }
- 185 }
- 186 }
- 187
- 188 System.exit(error ? 1 : 0 );
- 189 } // end main
- 190
- 191 }
代码中第137行ftp .enterLocalPassiveMode();
然后我查了api相关的几个方法 enterLocalActiveMode,enterRemoteActiveMode,enterRemotePassiveMode。
我的理解大概是这样的
enterLocalPassiveMode:设置客户端PASV模式
static int PASSIVE_LOCAL_DATA_CONNECTION_MODE
enterLocalActiveMode:设置客户端PORT模式
static int ACTIVE_LOCAL_DATA_CONNECTION_MODE
enterRemoteActiveMode:server to server
static int ACTIVE_REMOTE_DATA_CONNECTION_MODE
requiring the one(client) connect to the other server's data port to initiate a data transfer.
enterRemotePassiveMode:server to server
static int PASSIVE_REMOTE_DATA_CONNECTION_MODE
requiring the other server to connect to the first server's data port to initiate a data transfer
对FTP 协议了解的不太清楚是一个很大的原因,有时间要看看FTP 协议的内容了。
查了一些资料:
FTP 传输有两种模式:主 动模式(PORT)和被动模式(PASV)
主动模式:客户端主动连服务器端;端口用20
被动模式:服务器端连客户端;随机打开一个高端端口(端口号大于1024)
小提示 :有防火墙用户不能使用主动模式 ,这是因为防火墙不允许来自网外的主动连接,所以用户必须同使用被动模 式。
//enterLocalPassiveMode:设置客户端PASV模式 (客户端主动连服务器端;端口用20)
ftpClient.enterLocalPassiveMode();
//enterLocalActiveMode:设置客户端PORT模式 (服务器端连客户端;随机打开一个高端端口(端口号大于1024))
ftpClient.enterLocalActiveMode();
package com.ftp.test.apache;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.net.ftp.FTPClient;
public class FtpTest {
public static void main(String[] args) {
//testUpload();
testDownload();
}
/**
* FTP上传单个文件测试
*/
public static void testUpload() {
FTPClient ftpClient = new FTPClient();
FileInputStream fis = null;
try {
ftpClient.connect("服务器ip",端口);
ftpClient.login("用户名", "密码");
File srcFile = new File("路径+本地文件名");
fis = new FileInputStream(srcFile);
//enterLocalPassiveMode:设置客户端PASV模式 (客户端主动连服务器端;端口用20)
//enterLocalActiveMode:设置客户端PORT模式 (服务器端连客户端;随机打开一个高端端口(端口号大于1024))
ftpClient.enterLocalPassiveMode();
//ftpClient.enterLocalActiveMode();
//设置上传目录
ftpClient.changeWorkingDirectory("/");
ftpClient.setBufferSize(1024);
ftpClient.setControlEncoding("GBK");
//设置文件类型(二进制)
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.storeFile("远程文件名", fis);
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(fis);
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("关闭FTP 连接发生异常!", e);
}
}
}
/**
* FTP下载单个文件测试
*/
public static void testDownload() {
FTPClient ftpClient = new FTPClient();
FileOutputStream fos = null;
try {
ftpClient.connect("服务器ip",端口);
ftpClient.login("用户名", "密码");
ftpClient.enterLocalPassiveMode();
//远程文件名
String remoteFileName = "/index.jsp";
//本地文件
fos = new FileOutputStream("e:/down.jsp");
ftpClient.setBufferSize(1024);
//设置文件类型(二进制)
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.retrieveFile(remoteFileName, fos);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("FTP客户端出错!", e);
} finally {
IOUtils.closeQuietly(fos);
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("关闭FTP 连接发生异常!", e);
}
}
}
}
//sun
package com.ftp.test;
import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import sun.net.*;
import sun.net.ftp.FtpClient;
public class TestFtpClient {
public FtpClient ftpClient = null;
/**
* connectServer
* 连接ftp服务器
* @throws java.io.IOException
* @param path 文件夹,空代表根目录
* @param password 密码
* @param user 登陆用户
* @param server 服务器地址
*/
public void connectServer(String server, String user, String password,
String path) throws IOException {
// server:FTP 服务器的IP地址;user:登录FTP服务器的用户名
// password:登录FTP服务器的用户名的口令;path:FTP服务器上的路径
ftpClient = new FtpClient();
ftpClient.openServer(server);
ftpClient.login(user, password);
//path 是ftp服务下主目录的子目录
if (path.length() != 0)
ftpClient.cd(path);
//用2进制上传、下载
ftpClient.binary();
}
/**
* upload
* 上传文件
* @throws java.lang.Exception
* @return -1 文件不存在
* -2 文件内容为空
* >0 成功上传,返回文件的大小
* @param newname 上传后的新文件名
* @param filename 上传的文件
*/
public long upload(String filename, String newname) throws Exception {
long result = 0;
TelnetOutputStream os = null;
FileInputStream is = null;
try {
java.io.File file_in = new java.io.File(filename);
if (!file_in.exists())
return -1;
if (file_in.length() == 0)
return -2;
System.out.println(newname);
os = ftpClient.put(newname);
result = file_in.length();
is = new FileInputStream(file_in);
byte[] bytes = new byte[1024];
int c;
while ((c = is.read(bytes)) != -1) {
os.write(bytes, 0, c);
}
} finally {
if (is != null) {
is.close();
}
if (os != null) {
os.close();
}
}
return result;
}
/**
* upload
* @throws java.lang.Exception
* @return
* @param filename
*/
public long upload(String filename) throws Exception {
String newname = "";
if (filename.indexOf("/") > -1) {
newname = filename.substring(filename.lastIndexOf("/") + 1);
} else {
newname = filename;
}
return upload(filename, newname);
}
/**
* download
* 从ftp下载文件到本地
* @throws java.lang.Exception
* @return
* @param newfilename 本地生成的文件名
* @param filename 服务器上的文件名
*/
public long download(String filename, String newfilename) throws Exception {
long result = 0;
TelnetInputStream is = null;
FileOutputStream os = null;
try {
is = ftpClient.get(filename);
java.io.File outfile = new java.io.File(newfilename);
os = new FileOutputStream(outfile);
byte[] bytes = new byte[1024];
int c;
while ((c = is.read(bytes)) != -1) {
os.write(bytes, 0, c);
result = result + c;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
is.close();
}
if (os != null) {
os.close();
}
}
return result;
}
/**
* 取得某个目录下的所有文件列表
*
*/
public List getFileList(String path) {
List list = new ArrayList();
try {
DataInputStream dis = new DataInputStream(ftpClient.nameList(path));
String filename = "";
while ((filename = dis.readLine()) != null) {
list.add(filename);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
* closeServer
* 断开与ftp服务器的链接
* @throws java.io.IOException
*/
public void closeServer() throws IOException {
try {
if (ftpClient != null) {
ftpClient.closeServer();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
TestFtpClient ftp = new TestFtpClient();
try {
//连接ftp服务器
ftp.connectServer("服务器", "用户名", "密码", "目录");
/** 上传文件到 info2 文件夹下 */
//System.out.println("filesize:"+ ftp.upload("e:/info.log") + "字节");
/** 取得info2文件夹下的所有文件列表,并下载到 E盘下 */
List list = ftp.getFileList("/htdocs");
System.out.println(list.size());
for (int i = 0; i < list.size(); i++) {
String filename = (String) list.get(i);
System.out.println(filename);
ftp.download(filename, "E:/" + filename);
}
} catch (Exception e) {
//e.printStackTrace();
} finally {
//很重要
ftp.closeServer();
}
}
}