FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(Application)。基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。在FTP的使用当中,用户经常遇到两个概念:"下载"(Download)和"上传"(Upload)。"下载"文件就是从远程主机拷贝文件至自己的计算机上;"上传"文件就是将文件从自己的计算机中拷贝至远程主机上。用Internet语言来说,用户可通过客户机程序向(从)远程主机上传(下载)文件。

  首先下载了Serv-U将自己的电脑设置为了FTP文件服务器,方便操作。下面代码的使用都是在FTP服务器已经创建,并且要在代码中写好FTP连接的相关数据才可以完成。


1.FTP文件的上传与下载(注意是单个文件的上传与下载)


1 import java.io.File;
2 import java.io.FileInputStream;
3 import java.io.FileNotFoundException;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.OutputStream;
8
9 import org.apache.commons.net.ftp.FTP;
10 import org.apache.commons.net.ftp.FTPClient;
11 import org.apache.commons.net.ftp.FTPFile;
12 import org.apache.commons.net.ftp.FTPReply;
13
14 /**
15 * 实现FTP文件上传和文件下载
16 */
17 public class FtpApche {
18 private static FTPClient ftpClient = new FTPClient();
19 private static String encoding = System.getProperty("file.encoding");
20 /**
21 * Description: 向FTP服务器上传文件
22 *
23 * @Version1.0
24 * @param url
25 * FTP服务器hostname
26 * @param port
27 * FTP服务器端口
28 * @param username
29 * FTP登录账号
30 * @param password
31 * FTP登录密码
32 * @param path
33 * FTP服务器保存目录,如果是根目录则为“/”
34 * @param filename
35 * 上传到FTP服务器上的文件名
36 * @param input
37 * 本地文件输入流
38 * @return 成功返回true,否则返回false
39 */
40 public static boolean uploadFile(String url, int port, String username,
41 String password, String path, String filename, InputStream input) {
42 boolean result = false;
43
44 try {
45 int reply;
46 // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
47 ftpClient.connect(url);
48 // ftp.connect(url, port);// 连接FTP服务器
49 // 登录
50 ftpClient.login(username, password);
51 ftpClient.setControlEncoding(encoding);
52 // 检验是否连接成功
53 reply = ftpClient.getReplyCode();
54 if (!FTPReply.isPositiveCompletion(reply)) {
55 System.out.println("连接失败");
56 ftpClient.disconnect();
57 return result;
58 }
59
60 // 转移工作目录至指定目录下
61 boolean change = ftpClient.changeWorkingDirectory(path);
62 ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
63 if (change) {
64 result = ftpClient.storeFile(new String(filename.getBytes(encoding),"iso-8859-1"), input);
65 if (result) {
66 System.out.println("上传成功!");
67 }
68 }
69 input.close();
70 ftpClient.logout();
71 } catch (IOException e) {
72 e.printStackTrace();
73 } finally {
74 if (ftpClient.isConnected()) {
75 try {
76 ftpClient.disconnect();
77 } catch (IOException ioe) {
78 }
79 }
80 }
81 return result;
82 }
83
84 /**
85 * 将本地文件上传到FTP服务器上
86 *
87 */
88 public void testUpLoadFromDisk() {
89 try {
90 FileInputStream in = new FileInputStream(new File("D:/test02/list.txt"));
91 boolean flag = uploadFile("10.0.0.102", 21, "admin","123456", "/", "lis.txt", in);
92 System.out.println(flag);
93 } catch (FileNotFoundException e) {
94 e.printStackTrace();
95 }
96 }
97
98
99 /**
100 * Description: 从FTP服务器下载文件
101 *
102 * @Version1.0
103 * @param url
104 * FTP服务器hostname
105 * @param port
106 * FTP服务器端口
107 * @param username
108 * FTP登录账号
109 * @param password
110 * FTP登录密码
111 * @param remotePath
112 * FTP服务器上的相对路径
113 * @param fileName
114 * 要下载的文件名
115 * @param localPath
116 * 下载后保存到本地的路径
117 * @return
118 */
119 public static boolean downFile(String url, int port, String username,
120 String password, String remotePath, String fileName,
121 String localPath) {
122 boolean result = false;
123 try {
124 int reply;
125 ftpClient.setControlEncoding(encoding);
126
127 /*
128 * 为了上传和下载中文文件,有些地方建议使用以下两句代替
129 * new String(remotePath.getBytes(encoding),"iso-8859-1")转码。
130 * 经过测试,通不过。
131 */
132 // FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
133 // conf.setServerLanguageCode("zh");
134
135 ftpClient.connect(url, port);
136 // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
137 ftpClient.login(username, password);// 登录
138 // 设置文件传输类型为二进制
139 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
140 // 获取ftp登录应答代码
141 reply = ftpClient.getReplyCode();
142 // 验证是否登陆成功
143 if (!FTPReply.isPositiveCompletion(reply)) {
144 ftpClient.disconnect();
145 System.err.println("FTP server refused connection.");
146 return result;
147 }
148 // 转移到FTP服务器目录至指定的目录下
149 ftpClient.changeWorkingDirectory(new String(remotePath.getBytes(encoding),"iso-8859-1"));
150 // 获取文件列表
151 FTPFile[] fs = ftpClient.listFiles();
152 for (FTPFile ff : fs) {
153 if (ff.getName().equals(fileName)) {
154 File localFile = new File(localPath + "/" + ff.getName());
155 OutputStream is = new FileOutputStream(localFile);
156 ftpClient.retrieveFile(ff.getName(), is);
157 is.close();
158 }
159 }
160
161 ftpClient.logout();
162 result = true;
163 } catch (IOException e) {
164 e.printStackTrace();
165 } finally {
166 if (ftpClient.isConnected()) {
167 try {
168 ftpClient.disconnect();
169 } catch (IOException ioe) {
170 }
171 }
172 }
173 return result;
174 }
175
176 /**
177 * 将FTP服务器上文件下载到本地
178 *
179 */
180 public void testDownFile() {
181 try {
182 boolean flag = downFile("10.0.0.102", 21, "admin",
183 "123456", "/", "ip.txt", "E:/");
184 System.out.println(flag);
185 } catch (Exception e) {
186 e.printStackTrace();
187 }
188 }
189
190 public static void main(String[] args) {
191 FtpApche fa = new FtpApche();
192 fa.testDownFile();
193 fa.testUpLoadFromDisk();
194 }
195 }


2.FTP文件夹的上传与下载(注意是整个文件夹)


1 package ftp;
2
3 import java.io.BufferedInputStream;
4 import java.io.BufferedOutputStream;
5 import java.io.File;
6 import java.io.FileInputStream;
7 import java.io.FileNotFoundException;
8 import java.io.FileOutputStream;
9 import java.io.IOException;
10 import java.util.TimeZone;
11 import org.apache.commons.net.ftp.FTPClient;
12 import org.apache.commons.net.ftp.FTPClientConfig;
13 import org.apache.commons.net.ftp.FTPFile;
14 import org.apache.commons.net.ftp.FTPReply;
15
16 import org.apache.log4j.Logger;
17
18 public class FTPTest_04 {
19 private FTPClient ftpClient;
20 private String strIp;
21 private int intPort;
22 private String user;
23 private String password;
24
25 private static Logger logger = Logger.getLogger(FTPTest_04.class.getName());
26
27 /* *
28 * Ftp构造函数
29 */
30 public FTPTest_04(String strIp, int intPort, String user, String Password) {
31 this.strIp = strIp;
32 this.intPort = intPort;
33 this.user = user;
34 this.password = Password;
35 this.ftpClient = new FTPClient();
36 }
37 /**
38 * @return 判断是否登入成功
39 * */
40 public boolean ftpLogin() {
41 boolean isLogin = false;
42 FTPClientConfig ftpClientConfig = new FTPClientConfig();
43 ftpClientConfig.setServerTimeZoneId(TimeZone.getDefault().getID());
44 this.ftpClient.setControlEncoding("GBK");
45 this.ftpClient.configure(ftpClientConfig);
46 try {
47 if (this.intPort > 0) {
48 this.ftpClient.connect(this.strIp, this.intPort);
49 }else {
50 this.ftpClient.connect(this.strIp);
51 }
52 // FTP服务器连接回答
53 int reply = this.ftpClient.getReplyCode();
54 if (!FTPReply.isPositiveCompletion(reply)) {
55 this.ftpClient.disconnect();
56 logger.error("登录FTP服务失败!");
57 return isLogin;
58 }
59 this.ftpClient.login(this.user, this.password);
60 // 设置传输协议
61 this.ftpClient.enterLocalPassiveMode();
62 this.ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
63 logger.info("恭喜" + this.user + "成功登陆FTP服务器");
64 isLogin = true;
65 }catch (Exception e) {
66 e.printStackTrace();
67 logger.error(this.user + "登录FTP服务失败!" + e.getMessage());
68 }
69 this.ftpClient.setBufferSize(1024 * 2);
70 this.ftpClient.setDataTimeout(30 * 1000);
71 return isLogin;
72 }
73
74 /**
75 * @退出关闭服务器链接
76 * */
77 public void ftpLogOut() {
78 if (null != this.ftpClient && this.ftpClient.isConnected()) {
79 try {
80 boolean reuslt = this.ftpClient.logout();// 退出FTP服务器
81 if (reuslt) {
82 logger.info("成功退出服务器");
83 }
84 }catch (IOException e) {
85 e.printStackTrace();
86 logger.warn("退出FTP服务器异常!" + e.getMessage());
87 }finally {
88 try {
89 this.ftpClient.disconnect();// 关闭FTP服务器的连接
90 }catch (IOException e) {
91 e.printStackTrace();
92 logger.warn("关闭FTP服务器的连接异常!");
93 }
94 }
95 }
96 }
97
98 /***
99 * 上传Ftp文件
100 * @param localFile 当地文件
101 * @param romotUpLoadePath上传服务器路径 - 应该以/结束
102 * */
103 public boolean uploadFile(File localFile, String romotUpLoadePath) {
104 BufferedInputStream inStream = null;
105 boolean success = false;
106 try {
107 this.ftpClient.changeWorkingDirectory(romotUpLoadePath);// 改变工作路径
108 inStream = new BufferedInputStream(new FileInputStream(localFile));
109 logger.info(localFile.getName() + "开始上传.....");
110 success = this.ftpClient.storeFile(localFile.getName(), inStream);
111 if (success == true) {
112 logger.info(localFile.getName() + "上传成功");
113 return success;
114 }
115 }catch (FileNotFoundException e) {
116 e.printStackTrace();
117 logger.error(localFile + "未找到");
118 }catch (IOException e) {
119 e.printStackTrace();
120 }finally {
121 if (inStream != null) {
122 try {
123 inStream.close();
124 }catch (IOException e) {
125 e.printStackTrace();
126 }
127 }
128 }
129 return success;
130 }
131
132 /***
133 * 下载文件
134 * @param remoteFileName 待下载文件名称
135 * @param localDires 下载到当地那个路径下
136 * @param remoteDownLoadPath remoteFileName所在的路径
137 * */
138
139 public boolean downloadFile(String remoteFileName, String localDires,
140 String remoteDownLoadPath) {
141 String strFilePath = localDires + remoteFileName;
142 BufferedOutputStream outStream = null;
143 boolean success = false;
144 try {
145 this.ftpClient.changeWorkingDirectory(remoteDownLoadPath);
146 outStream = new BufferedOutputStream(new FileOutputStream(
147 strFilePath));
148 logger.info(remoteFileName + "开始下载....");
149 success = this.ftpClient.retrieveFile(remoteFileName, outStream);
150 if (success == true) {
151 logger.info(remoteFileName + "成功下载到" + strFilePath);
152 return success;
153 }
154 }catch (Exception e) {
155 e.printStackTrace();
156 logger.error(remoteFileName + "下载失败");
157 }finally {
158 if (null != outStream) {
159 try {
160 outStream.flush();
161 outStream.close();
162 }catch (IOException e) {
163 e.printStackTrace();
164 }
165 }
166 }
167 if (success == false) {
168 logger.error(remoteFileName + "下载失败!!!");
169 }
170 return success;
171 }
172
173 /***
174 * @上传文件夹
175 * @param localDirectory
176 * 当地文件夹
177 * @param remoteDirectoryPath
178 * Ftp 服务器路径 以目录"/"结束
179 * */
180 public boolean uploadDirectory(String localDirectory,
181 String remoteDirectoryPath) {
182 File src = new File(localDirectory);
183 try {
184 remoteDirectoryPath = remoteDirectoryPath + src.getName() + "/";
185 boolean makeDirFlag = this.ftpClient.makeDirectory(remoteDirectoryPath);
186 System.out.println("localDirectory : " + localDirectory);
187 System.out.println("remoteDirectoryPath : " + remoteDirectoryPath);
188 System.out.println("src.getName() : " + src.getName());
189 System.out.println("remoteDirectoryPath : " + remoteDirectoryPath);
190 System.out.println("makeDirFlag : " + makeDirFlag);
191 // ftpClient.listDirectories();
192 }catch (IOException e) {
193 e.printStackTrace();
194 logger.info(remoteDirectoryPath + "目录创建失败");
195 }
196 File[] allFile = src.listFiles();
197 for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
198 if (!allFile[currentFile].isDirectory()) {
199 String srcName = allFile[currentFile].getPath().toString();
200 uploadFile(new File(srcName), remoteDirectoryPath);
201 }
202 }
203 for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
204 if (allFile[currentFile].isDirectory()) {
205 // 递归
206 uploadDirectory(allFile[currentFile].getPath().toString(),
207 remoteDirectoryPath);
208 }
209 }
210 return true;
211 }
212
213 /***
214 * @下载文件夹
215 * @param localDirectoryPath本地地址
216 * @param remoteDirectory 远程文件夹
217 * */
218 public boolean downLoadDirectory(String localDirectoryPath,String remoteDirectory) {
219 try {
220 String fileName = new File(remoteDirectory).getName();
221 localDirectoryPath = localDirectoryPath + fileName + "//";
222 new File(localDirectoryPath).mkdirs();
223 FTPFile[] allFile = this.ftpClient.listFiles(remoteDirectory);
224 for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
225 if (!allFile[currentFile].isDirectory()) {
226 downloadFile(allFile[currentFile].getName(),localDirectoryPath, remoteDirectory);
227 }
228 }
229 for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
230 if (allFile[currentFile].isDirectory()) {
231 String strremoteDirectoryPath = remoteDirectory + "/"+ allFile[currentFile].getName();
232 downLoadDirectory(localDirectoryPath,strremoteDirectoryPath);
233 }
234 }
235 }catch (IOException e) {
236 e.printStackTrace();
237 logger.info("下载文件夹失败");
238 return false;
239 }
240 return true;
241 }
242 // FtpClient的Set 和 Get 函数
243 public FTPClient getFtpClient() {
244 return ftpClient;
245 }
246 public void setFtpClient(FTPClient ftpClient) {
247 this.ftpClient = ftpClient;
248 }
249
250 public static void main(String[] args) throws IOException {
251 FTPTest_04 ftp=new FTPTest_04("10.0.0.102",21,"admin","123456");
252 ftp.ftpLogin();
253 System.out.println("1");
254 //上传文件夹
255 boolean uploadFlag = ftp.uploadDirectory("D:\\test02", "/"); //如果是admin/那么传的就是所有文件,如果只是/那么就是传文件夹
256 System.out.println("uploadFlag : " + uploadFlag);
257 //下载文件夹
258 ftp.downLoadDirectory("d:\\tm", "/");
259 ftp.ftpLogOut();
260 }
261 }