实现FTP文件上传与下载可以通过以下两种种方式实现(不知道还有没有其他方式),分别为:1、通过JDK自带的API实现;2、通过Apache提供的API是实现。
第一种方式
001 | package com.cloudpower.util; |
002 | |
003 | import java.io.File; |
004 | import java.io.FileInputStream; |
005 | import java.io.FileOutputStream; |
006 | import java.io.IOException; |
007 | |
008 | import sun.net.TelnetInputStream; |
009 | import sun.net.TelnetOutputStream; |
010 | import sun.net.ftp.FtpClient; |
011 | |
012 | /** |
013 | * Java自带的API对FTP的操作 |
014 | * @Title:Ftp.java |
015 | * @author: 周玲斌 |
016 | */ |
017 | public class Ftp { |
018 | /** |
019 | * 本地文件名 |
020 | */ |
021 | private String localfilename; |
022 | /** |
023 | * 远程文件名 |
024 | */ |
025 | private String remotefilename; |
026 | /** |
027 | * FTP客户端 |
028 | */ |
029 | private FtpClient ftpClient; |
030 | |
031 | /** |
032 | * 服务器连接 |
033 | * @param ip 服务器IP |
034 | * @param port 服务器端口 |
035 | * @param user 用户名 |
036 | * @param password 密码 |
037 | * @param path 服务器路径 |
038 | * @author 周玲斌 |
039 | * @date 2012-7-11 |
040 | */ |
041 | public void connectServer(String ip, int port, String user, |
042 | String password, String path) { |
043 | try { |
044 | /* ******连接服务器的两种方法*******/ |
045 | //第一种方法 |
046 | // ftpClient = new FtpClient(); |
047 | // ftpClient.openServer(ip, port); |
048 | //第二种方法 |
049 | ftpClient = new FtpClient(ip); |
050 | |
051 | ftpClient.login(user, password); |
052 | // 设置成2进制传输 |
053 | ftpClient.binary(); |
054 | System.out.println("login success!"); |
055 | if (path.length() != 0){ |
056 | //把远程系统上的目录切换到参数path所指定的目录 |
057 | ftpClient.cd(path); |
058 | } |
059 | ftpClient.binary(); |
060 | } catch (IOException ex) { |
061 | ex.printStackTrace(); |
062 | throw new RuntimeException(ex); |
063 | } |
064 | } |
065 | /** |
066 | * 关闭连接 |
067 | * @author 周玲斌 |
068 | * @date 2012-7-11 |
069 | */ |
070 | public void closeConnect() { |
071 | try { |
072 | ftpClient.closeServer(); |
073 | System.out.println("disconnect success"); |
074 | } catch (IOException ex) { |
075 | System.out.println("not disconnect"); |
076 | ex.printStackTrace(); |
077 | throw new RuntimeException(ex); |
078 | } |
079 | } |
080 | /** |
081 | * 上传文件 |
082 | * @param localFile 本地文件 |
083 | * @param remoteFile 远程文件 |
084 | * @author 周玲斌 |
085 | * @date 2012-7-11 |
086 | */ |
087 | public void upload(String localFile, String remoteFile) { |
088 | this.localfilename = localFile; |
089 | this.remotefilename = remoteFile; |
090 | TelnetOutputStream os = null; |
091 | FileInputStream is = null; |
092 | try { |
093 | //将远程文件加入输出流中 |
094 | os = ftpClient.put(this.remotefilename); |
095 | //获取本地文件的输入流 |
096 | File file_in = new File(this.localfilename); |
097 | is = new FileInputStream(file_in); |
098 | //创建一个缓冲区 |
099 | byte[] bytes = new byte[1024]; |
100 | int c; |
101 | while ((c = is.read(bytes)) != -1) { |
102 | os.write(bytes, 0, c); |
103 | } |
104 | System.out.println("upload success"); |
105 | } catch (IOException ex) { |
106 | System.out.println("not upload"); |
107 | ex.printStackTrace(); |
108 | throw new RuntimeException(ex); |
109 | } finally{ |
110 | try { |
111 | if(is != null){ |
112 | is.close(); |
113 | } |
114 | } catch (IOException e) { |
115 | e.printStackTrace(); |
116 | } finally { |
117 | try { |
118 | if(os != null){ |
119 | os.close(); |
120 | } |
121 | } catch (IOException e) { |
122 | e.printStackTrace(); |
123 | } |
124 | } |
125 | } |
126 | } |
127 | |
128 | /** |
129 | * 下载文件 |
130 | * @param remoteFile 远程文件路径(服务器端) |
131 | * @param localFile 本地文件路径(客户端) |
132 | * @author 周玲斌 |
133 | * @date 2012-7-11 |
134 | */ |
135 | public void download(String remoteFile, String localFile) { |
136 | TelnetInputStream is = null; |
137 | FileOutputStream os = null; |
138 | try { |
139 | //获取远程机器上的文件filename,借助TelnetInputStream把该文件传送到本地。 |
140 | is = ftpClient.get(remoteFile); |
141 | File file_in = new File(localFile); |
142 | os = new FileOutputStream(file_in); |
143 | byte[] bytes = new byte[1024]; |
144 | int c; |
145 | while ((c = is.read(bytes)) != -1) { |
146 | os.write(bytes, 0, c); |
147 | } |
148 | System.out.println("download success"); |
149 | } catch (IOException ex) { |
150 | System.out.println("not download"); |
151 | ex.printStackTrace(); |
152 | throw new RuntimeException(ex); |
153 | } finally{ |
154 | try { |
155 | if(is != null){ |
156 | is.close(); |
157 | } |
158 | } catch (IOException e) { |
159 | e.printStackTrace(); |
160 | } finally { |
161 | try { |
162 | if(os != null){ |
163 | os.close(); |
164 | } |
165 | } catch (IOException e) { |
166 | e.printStackTrace(); |
167 | } |
168 | } |
169 | } |
170 | } |
171 | |
172 | public static void main(String agrs[]) { |
173 | |
174 | String filepath[] = { "/temp/aa.txt", "/temp/regist.log"}; |
175 | String localfilepath[] = { "C:\\tmp\\1.txt","C:\\tmp\\2.log"}; |
176 | |
177 | Ftp fu = new Ftp(); |
178 | /* |
179 | * 使用默认的端口号、用户名、密码以及根目录连接FTP服务器 |
180 | */ |
181 | fu.connectServer( "127.0.0.1" , 22 , "anonymous" , "IEUser@" , "/temp" ); |
182 | |
183 | //下载 |
184 | for ( int i = 0 ; i < filepath.length; i++) { |
185 | fu.download(filepath[i], localfilepath[i]); |
186 | } |
187 | |
188 | String localfile = "E:\\号码.txt" ; |
189 | String remotefile = "/temp/哈哈.txt" ; |
190 | //上传 |
191 | fu.upload(localfile, remotefile); |
192 | fu.closeConnect(); |
193 | } |
194 | } |
第二种方式
001 | public class FtpApche { |
002 | private static FTPClient ftpClient = new FTPClient(); |
003 | private static String encoding = System.getProperty( "file.encoding" ); |
004 | /** |
005 | * Description: 向FTP服务器上传文件 |
006 | * |
007 | * @Version1.0 |
008 | * @param url |
009 | * FTP服务器hostname |
010 | * @param port |
011 | * FTP服务器端口 |
012 | * @param username |
013 | * FTP登录账号 |
014 | * @param password |
015 | * FTP登录密码 |
016 | * @param path |
017 | * FTP服务器保存目录,如果是根目录则为“/” |
018 | * @param filename |
019 | * 上传到FTP服务器上的文件名 |
020 | * @param input |
021 | * 本地文件输入流 |
022 | * @return 成功返回true,否则返回false |
023 | */ |
024 | public static boolean uploadFile(String url, int port, String username, |
025 | String password, String path, String filename, InputStream input) { |
026 | boolean result = false ; |
027 | |
028 | try { |
029 | int reply; |
030 | // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器 |
031 | ftpClient.connect(url); |
032 | // ftp.connect(url, port);// 连接FTP服务器 |
033 | // 登录 |
034 | ftpClient.login(username, password); |
035 | ftpClient.setControlEncoding(encoding); |
036 | // 检验是否连接成功 |
037 | reply = ftpClient.getReplyCode(); |
038 | if (!FTPReply.isPositiveCompletion(reply)) { |
039 | System.out.println( "连接失败" ); |
040 | ftpClient.disconnect(); |
041 | return result; |
042 | } |
043 | |
044 | // 转移工作目录至指定目录下 |
045 | boolean change = ftpClient.changeWorkingDirectory(path); |
046 | ftpClient.setFileType(FTP.BINARY_FILE_TYPE); |
047 | if (change) { |
048 | result = ftpClient.storeFile( new String(filename.getBytes(encoding), "iso-8859-1" ), input); |
049 | if (result) { |
050 | System.out.println( "上传成功!" ); |
051 | } |
052 | } |
053 | input.close(); |
054 | ftpClient.logout(); |
055 | } catch (IOException e) { |
056 | e.printStackTrace(); |
057 | } finally { |
058 | if (ftpClient.isConnected()) { |
059 | try { |
060 | ftpClient.disconnect(); |
061 | } catch (IOException ioe) { |
062 | } |
063 | } |
064 | } |
065 | return result; |
066 | } |
067 | |
068 | /** |
069 | * 将本地文件上传到FTP服务器上 |
070 | * |
071 | */ |
072 | public void testUpLoadFromDisk() { |
073 | try { |
074 | FileInputStream in = new FileInputStream( new File( "E:/号码.txt" )); |
075 | boolean flag = uploadFile( "127.0.0.1" , 21 , "zlb" , "123" , "/" , "哈哈.txt" , in); |
076 | System.out.println(flag); |
077 | } catch (FileNotFoundException e) { |
078 | e.printStackTrace(); |
079 | } |
080 | } |
081 | |
082 | |
083 | /** |
084 | * Description: 从FTP服务器下载文件 |
085 | * |
086 | * @Version1.0 |
087 | * @param url |
088 | * FTP服务器hostname |
089 | * @param port |
090 | * FTP服务器端口 |
091 | * @param username |
092 | * FTP登录账号 |
093 | * @param password |
094 | * FTP登录密码 |
095 | * @param remotePath |
096 | * FTP服务器上的相对路径 |
097 | * @param fileName |
098 | * 要下载的文件名 |
099 | * @param localPath |
100 | * 下载后保存到本地的路径 |
101 | * @return |
102 | */ |
103 | public static boolean downFile(String url, int port, String username, |
104 | String password, String remotePath, String fileName, |
105 | String localPath) { |
106 | boolean result = false ; |
107 | try { |
108 | int reply; |
109 | ftpClient.setControlEncoding(encoding); |
110 | |
111 | /* |
112 | * 为了上传和下载中文文件,有些地方建议使用以下两句代替 |
113 | * new String(remotePath.getBytes(encoding),"iso-8859-1")转码。 |
114 | * 经过测试,通不过。 |
115 | */ |
116 | // FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT); |
117 | // conf.setServerLanguageCode("zh"); |
118 | |
119 | ftpClient.connect(url, port); |
120 | // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器 |
121 | ftpClient.login(username, password);// 登录 |
122 | // 设置文件传输类型为二进制 |
123 | ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); |
124 | // 获取ftp登录应答代码 |
125 | reply = ftpClient.getReplyCode(); |
126 | // 验证是否登陆成功 |
127 | if (!FTPReply.isPositiveCompletion(reply)) { |
128 | ftpClient.disconnect(); |
129 | System.err.println("FTP server refused connection."); |
130 | return result; |
131 | } |
132 | // 转移到FTP服务器目录至指定的目录下 |
133 | ftpClient.changeWorkingDirectory(new String(remotePath.getBytes(encoding),"iso-8859-1")); |
134 | // 获取文件列表 |
135 | FTPFile[] fs = ftpClient.listFiles(); |
136 | for (FTPFile ff : fs) { |
137 | if (ff.getName().equals(fileName)) { |
138 | File localFile = new File(localPath + "/" + ff.getName()); |
139 | OutputStream is = new FileOutputStream(localFile); |
140 | ftpClient.retrieveFile(ff.getName(), is); |
141 | is.close(); |
142 | } |
143 | } |
144 | |
145 | ftpClient.logout(); |
146 | result = true; |
147 | } catch (IOException e) { |
148 | e.printStackTrace(); |
149 | } finally { |
150 | if (ftpClient.isConnected()) { |
151 | try { |
152 | ftpClient.disconnect(); |
153 | } catch (IOException ioe) { |
154 | } |
155 | } |
156 | } |
157 | return result; |
158 | } |
159 | |
160 | /** |
161 | * 将FTP服务器上文件下载到本地 |
162 | * |
163 | */ |
164 | public void testDownFile() { |
165 | try { |
166 | boolean flag = downFile( "127.0.0.1" , 21 , "zlb" , |
167 | "123" , "/" , "哈哈.txt" , "D:/" ); |
168 | System.out.println(flag); |
169 | } catch (Exception e) { |
170 | e.printStackTrace(); |
171 | } |
172 | } |
173 | |
174 | public static void main(String[] args) { |
175 | FtpApche fa = new FtpApche(); |
176 | fa.testDownFile(); |
177 | } |
178 | } |
1、加上以下三句即可解决
ftpClient.setControlEncoding(“GBK”);
FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
conf.setServerLanguageCode("zh");
解答:经过测试,根本上行不通,上述问题依然存在
2、与上述方式有所类似,但我觉得这种方式更靠谱一点
首先,加上ftpClient.setControlEncoding(“GBK”);这一句,然后,将所有的中文进行转码为“ISO-8859-1”格式,如下:
ftpClient.changeWorkingDirectory(new String(remotePath.getBytes("GBK"),"iso-8859-1"));
解答:经过测试,仍然行不通,之所以我说此方式更靠谱一点,请继续往下看
首先我们来说说为什么要进行转码:
因为在FTP协议里面,规定文件名编码为iso-8859-1,所以目录名或文件名需要转码。
接下来的问题是,我们应该将什么编码转换为此格式。因此,就有了第二种解决方案——把 GBK格式的转换为ISO-8859-1格式。而且,有的人还说,必须得这么转。其实,之所以他们能这么说,我觉得完全是巧合。它的真正原理是,既然 FTP协议规定的编码格式是“ISO-8859-1”,那么我们确实得将格式转换一下,然后等服务器收到文件时再自动转换为系统自带的编码格式,因此,关键不是规定为什么格式,而是取决于FTP服务器的编码格式。因此,如果FTP系统的编码格式为“GBK”时,第二种方式肯定会成功;但是,如果系统的编码格式为“UTF-8”时,那就会仍然出现乱码啦。所以,我们只能通过代码先获取系统的编码格式,然后通过此编码格式转换为ISO-8859-1的编码格式。获取方式如下:
private static String encoding = System.getProperty("file.encoding");
以上代码均通过自己测试,望能为大家解决一下问题!转自:http://blog.csdn.net/zlb824/article/details/7742959