socket实现的ftp 被动式下载(android平台)
android平台上没有现成的ftp工具类,网上的找了ftp的socket实现,发现都是主动式;如是自己改写了一下Paul Mutton的SimpleFTP,添加了get 和list,并把get的文件放到files目录下。
(并没有参考完整的ftp协议)
1
package
com.jhsys.wang.t1;
2 import java.io.BufferedInputStream;
3 import java.io.BufferedOutputStream;
4 import java.io.BufferedReader;
5 import java.io.BufferedWriter;
6 import java.io.File;
7 import java.io.FileInputStream;
8 import java.io.FileOutputStream;
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.io.InputStreamReader;
12 import java.io.OutputStreamWriter;
13 import java.net.Socket;
14 import java.util.StringTokenizer;
15 import java.util.Vector;
16
17 import android.content.Context;
18
19 /**
20 * SimpleFTP is a simple package that implements a Java FTP client. With
21 * SimpleFTP, you can connect to an FTP server and upload multiple files.
22 * <p>
23 * Copyright Paul Mutton, <a
24 * href=" http://www.jibble.org/ "> http://www.jibble.org/ </a>
25 *
26 */
27 public class SimpleFTP {
28
29 private Context context;
30
31 /**
32 * Create an instance of SimpleFTP.
33 */
34 public SimpleFTP(Context context) {
35 this .context = context;
36 }
37
38 /**
39 * Connects to the default port of an FTP server and logs in as
40 * anonymous/anonymous.
41 */
42 public synchronized void connect(String host) throws IOException {
43 connect(host, 21 );
44 }
45
46 /**
47 * Connects to an FTP server and logs in as anonymous/anonymous.
48 */
49 public synchronized void connect(String host, int port) throws IOException {
50 connect(host, port, " anonymous " , " anonymous " );
51 }
52
53 /**
54 * Connects to an FTP server and logs in with the supplied username and
55 * password.
56 */
57 public synchronized void connect(String host, int port, String user,
58 String pass) throws IOException {
59 if (socket != null ) {
60 throw new IOException( " SimpleFTP is already connected. Disconnect first. " );
61 }
62 socket = new Socket(host, port);
63 reader = new BufferedReader( new InputStreamReader(socket.getInputStream()));
64 writer = new BufferedWriter(
65 new OutputStreamWriter(socket.getOutputStream()));
66
67 String response = readLine();
68 if ( ! response.startsWith( " 220 " )) {
69 throw new IOException(
70 " SimpleFTP received an unknown response when connecting to the FTP server: "
71 + response);
72 }
73
74 sendLine( " USER " + user);
75
76 response = readLine();
77 if ( ! response.startsWith( " 331 " )) {
78 throw new IOException(
79 " SimpleFTP received an unknown response after sending the user: "
80 + response);
81 }
82
83 sendLine( " PASS " + pass);
84
85 response = readLine();
86 if ( ! response.startsWith( " 230 " )) {
87 throw new IOException(
88 " SimpleFTP was unable to log in with the supplied password: "
89 + response);
90 }
91
92 // Now logged in.
93 }
94
95 /**
96 * Disconnects from the FTP server.
97 */
98 public synchronized void disconnect() throws IOException {
99 try {
100 sendLine( " QUIT " );
101 } finally {
102 socket = null ;
103 }
104 }
105
106 /**
107 * Returns the working directory of the FTP server it is connected to.
108 */
109 public synchronized String pwd() throws IOException {
110 sendLine( " PWD " );
111 String dir = null ;
112 String response = readLine();
113 if (response.startsWith( " 257 " )) {
114 int firstQuote = response.indexOf( ' \" ' );
115 int secondQuote = response.indexOf( ' \" ' , firstQuote + 1 );
116 if (secondQuote > 0 ) {
117 dir = response.substring(firstQuote + 1 , secondQuote);
118 }
119 }
120 return dir;
121 }
122
123 /**
124 * Changes the working directory (like cd). Returns true if successful.
125 */
126 public synchronized boolean cwd(String dir) throws IOException {
127 sendLine( " CWD " + dir);
128 String response = readLine();
129 return (response.startsWith( " 250 " ));
130 }
131
132 /**
133 * Sends a file to be stored on the FTP server. Returns true if the file
134 * transfer was successful. The file is sent in passive mode to avoid NAT or
135 * firewall problems at the client end.
136 */
137 public synchronized boolean stor(File file) throws IOException {
138 if (file.isDirectory()) {
139 throw new IOException( " SimpleFTP cannot upload a directory. " );
140 }
141
142 String filename = file.getName();
143
144 return stor( new FileInputStream(file), filename);
145 }
146
147 /**
148 * Sends a file to be stored on the FTP server. Returns true if the file
149 * transfer was successful. The file is sent in passive mode to avoid NAT or
150 * firewall problems at the client end.
151 */
152 public synchronized boolean stor(InputStream inputStream, String filename)
153 throws IOException {
154 BufferedInputStream input = new BufferedInputStream(inputStream);
155 Socket dataSocket = getConnection();
156 sendLine( " STOR " + filename);
157
158 String response = readLine();
159 if ( ! response.startsWith( " 150 " )) {
160 throw new IOException( " SimpleFTP was not allowed to send the file: "
161 + response);
162 }
163
164 BufferedOutputStream output = new BufferedOutputStream(dataSocket
165 .getOutputStream());
166 byte [] buffer = new byte [ 4096 ];
167 int bytesRead = 0 ;
168 while ((bytesRead = input.read(buffer)) != - 1 ) {
169 output.write(buffer, 0 , bytesRead);
170 }
171 output.flush();
172 output.close();
173 input.close();
174
175 response = readLine();
176 return response.startsWith( " 226 " );
177 }
178
179 /**
180 * Enter binary mode for sending binary files.
181 */
182 public synchronized boolean bin() throws IOException {
183 sendLine( " TYPE I " );
184 String response = readLine();
185 return (response.startsWith( " 200 " ));
186 }
187
188 /**
189 * Enter ASCII mode for sending text files. This is usually the default mode.
190 * Make sure you use binary mode if you are sending images or other binary
191 * data, as ASCII mode is likely to corrupt them.
192 */
193 public synchronized boolean ascii() throws IOException {
194 sendLine( " TYPE A " );
195 String response = readLine();
196 return (response.startsWith( " 200 " ));
197 }
198
199 /**
200 * Sends a raw command to the FTP server.
201 */
202 private void sendLine(String line) throws IOException {
203 if (socket == null ) {
204 throw new IOException( " SimpleFTP is not connected. " );
205 }
206 try {
207 writer.write(line + " \r\n " );
208 writer.flush();
209 if (DEBUG) {
210 System.out.println( " > " + line);
211 }
212 } catch (IOException e) {
213 socket = null ;
214 throw e;
215 }
216 }
217
218 private String readLine() throws IOException {
219 String line = reader.readLine();
220 if (DEBUG) {
221 System.out.println( " < " + line);
222 }
223 return line;
224 }
225
226 private Socket socket = null ;
227
228 private BufferedReader reader = null ;
229
230 private BufferedWriter writer = null ;
231
232 private static boolean DEBUG = true ;
233
234
235 // add by wanglinag 2010 9 2
236 public synchronized boolean get(String filename,String savename)
237 throws IOException {
238 Socket dataSocket = getConnection();
239 sendLine( " RETR " + filename);
240 String response = readLine();
241 if ( ! response.startsWith( " 150 " )) {
242 // if (!response.startsWith("150 ")) {
243 throw new IOException(
244 " SimpleFTP was not allowed to get the file: " + response);
245 }
246 FileOutputStream outfile = context.openFileOutput(savename,Context.MODE_WORLD_READABLE);
247 // 构造传输文件用的数据流
248 BufferedInputStream dataInput = new BufferedInputStream(dataSocket.getInputStream());
249 // 接收来自服务器的数据,写入本地文件
250 int n;
251 byte [] buff = new byte [ 1024 ];
252 while ((n = dataInput.read(buff)) > 0 ) {
253 outfile.write(buff, 0 , n);
254 }
255 dataSocket.close();
256 outfile.close();
257
258 response = readLine();
259 return response.startsWith( " 226 " );
260 }
261
262
263 public synchronized Vector < String > List() throws IOException{
264 Socket dataSocket = getConnection();
265 sendLine( " LIST " );
266 Vector < String > result = new Vector < String > ();
267 int n;
268 byte [] buff = new byte [ 65530 ];
269 // 准备读取数据用的流
270 BufferedInputStream dataInput = new BufferedInputStream(dataSocket
271 .getInputStream());
272 // 读取目录信息
273
274 while ((n = dataInput.read(buff)) > 0 ) {
275 System.out.write(buff, 0 , n);
276 result.add( new String(buff, 0 ,n));
277 }
278 dataSocket.close();
279 readLine();
280 readLine();
281
282 return result;
283 }
284
285
286 private Socket getConnection() throws IOException{
287 sendLine( " PASV " );
288 String response = readLine();
289 if ( ! response.startsWith( " 227 " )) {
290 throw new IOException( " SimpleFTP could not request passive mode: "
291 + response);
292 }
293
294 String ip = null ;
295 int port = - 1 ;
296 int opening = response.indexOf( ' ( ' );
297 int closing = response.indexOf( ' ) ' , opening + 1 );
298 if (closing > 0 ) {
299 String dataLink = response.substring(opening + 1 , closing);
300 StringTokenizer tokenizer = new StringTokenizer(dataLink, " , " );
301 try {
302 ip = tokenizer.nextToken() + " . " + tokenizer.nextToken() + " . "
303 + tokenizer.nextToken() + " . " + tokenizer.nextToken();
304 port = Integer.parseInt(tokenizer.nextToken()) * 256
305 + Integer.parseInt(tokenizer.nextToken());
306 } catch (Exception e) {
307 throw new IOException(
308 " SimpleFTP received bad data link information: "
309 + response);
310 }
311 }
312 Socket dataSocket = new Socket(ip, port);
313 return dataSocket;
314 }
315 }
316
2 import java.io.BufferedInputStream;
3 import java.io.BufferedOutputStream;
4 import java.io.BufferedReader;
5 import java.io.BufferedWriter;
6 import java.io.File;
7 import java.io.FileInputStream;
8 import java.io.FileOutputStream;
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.io.InputStreamReader;
12 import java.io.OutputStreamWriter;
13 import java.net.Socket;
14 import java.util.StringTokenizer;
15 import java.util.Vector;
16
17 import android.content.Context;
18
19 /**
20 * SimpleFTP is a simple package that implements a Java FTP client. With
21 * SimpleFTP, you can connect to an FTP server and upload multiple files.
22 * <p>
23 * Copyright Paul Mutton, <a
24 * href=" http://www.jibble.org/ "> http://www.jibble.org/ </a>
25 *
26 */
27 public class SimpleFTP {
28
29 private Context context;
30
31 /**
32 * Create an instance of SimpleFTP.
33 */
34 public SimpleFTP(Context context) {
35 this .context = context;
36 }
37
38 /**
39 * Connects to the default port of an FTP server and logs in as
40 * anonymous/anonymous.
41 */
42 public synchronized void connect(String host) throws IOException {
43 connect(host, 21 );
44 }
45
46 /**
47 * Connects to an FTP server and logs in as anonymous/anonymous.
48 */
49 public synchronized void connect(String host, int port) throws IOException {
50 connect(host, port, " anonymous " , " anonymous " );
51 }
52
53 /**
54 * Connects to an FTP server and logs in with the supplied username and
55 * password.
56 */
57 public synchronized void connect(String host, int port, String user,
58 String pass) throws IOException {
59 if (socket != null ) {
60 throw new IOException( " SimpleFTP is already connected. Disconnect first. " );
61 }
62 socket = new Socket(host, port);
63 reader = new BufferedReader( new InputStreamReader(socket.getInputStream()));
64 writer = new BufferedWriter(
65 new OutputStreamWriter(socket.getOutputStream()));
66
67 String response = readLine();
68 if ( ! response.startsWith( " 220 " )) {
69 throw new IOException(
70 " SimpleFTP received an unknown response when connecting to the FTP server: "
71 + response);
72 }
73
74 sendLine( " USER " + user);
75
76 response = readLine();
77 if ( ! response.startsWith( " 331 " )) {
78 throw new IOException(
79 " SimpleFTP received an unknown response after sending the user: "
80 + response);
81 }
82
83 sendLine( " PASS " + pass);
84
85 response = readLine();
86 if ( ! response.startsWith( " 230 " )) {
87 throw new IOException(
88 " SimpleFTP was unable to log in with the supplied password: "
89 + response);
90 }
91
92 // Now logged in.
93 }
94
95 /**
96 * Disconnects from the FTP server.
97 */
98 public synchronized void disconnect() throws IOException {
99 try {
100 sendLine( " QUIT " );
101 } finally {
102 socket = null ;
103 }
104 }
105
106 /**
107 * Returns the working directory of the FTP server it is connected to.
108 */
109 public synchronized String pwd() throws IOException {
110 sendLine( " PWD " );
111 String dir = null ;
112 String response = readLine();
113 if (response.startsWith( " 257 " )) {
114 int firstQuote = response.indexOf( ' \" ' );
115 int secondQuote = response.indexOf( ' \" ' , firstQuote + 1 );
116 if (secondQuote > 0 ) {
117 dir = response.substring(firstQuote + 1 , secondQuote);
118 }
119 }
120 return dir;
121 }
122
123 /**
124 * Changes the working directory (like cd). Returns true if successful.
125 */
126 public synchronized boolean cwd(String dir) throws IOException {
127 sendLine( " CWD " + dir);
128 String response = readLine();
129 return (response.startsWith( " 250 " ));
130 }
131
132 /**
133 * Sends a file to be stored on the FTP server. Returns true if the file
134 * transfer was successful. The file is sent in passive mode to avoid NAT or
135 * firewall problems at the client end.
136 */
137 public synchronized boolean stor(File file) throws IOException {
138 if (file.isDirectory()) {
139 throw new IOException( " SimpleFTP cannot upload a directory. " );
140 }
141
142 String filename = file.getName();
143
144 return stor( new FileInputStream(file), filename);
145 }
146
147 /**
148 * Sends a file to be stored on the FTP server. Returns true if the file
149 * transfer was successful. The file is sent in passive mode to avoid NAT or
150 * firewall problems at the client end.
151 */
152 public synchronized boolean stor(InputStream inputStream, String filename)
153 throws IOException {
154 BufferedInputStream input = new BufferedInputStream(inputStream);
155 Socket dataSocket = getConnection();
156 sendLine( " STOR " + filename);
157
158 String response = readLine();
159 if ( ! response.startsWith( " 150 " )) {
160 throw new IOException( " SimpleFTP was not allowed to send the file: "
161 + response);
162 }
163
164 BufferedOutputStream output = new BufferedOutputStream(dataSocket
165 .getOutputStream());
166 byte [] buffer = new byte [ 4096 ];
167 int bytesRead = 0 ;
168 while ((bytesRead = input.read(buffer)) != - 1 ) {
169 output.write(buffer, 0 , bytesRead);
170 }
171 output.flush();
172 output.close();
173 input.close();
174
175 response = readLine();
176 return response.startsWith( " 226 " );
177 }
178
179 /**
180 * Enter binary mode for sending binary files.
181 */
182 public synchronized boolean bin() throws IOException {
183 sendLine( " TYPE I " );
184 String response = readLine();
185 return (response.startsWith( " 200 " ));
186 }
187
188 /**
189 * Enter ASCII mode for sending text files. This is usually the default mode.
190 * Make sure you use binary mode if you are sending images or other binary
191 * data, as ASCII mode is likely to corrupt them.
192 */
193 public synchronized boolean ascii() throws IOException {
194 sendLine( " TYPE A " );
195 String response = readLine();
196 return (response.startsWith( " 200 " ));
197 }
198
199 /**
200 * Sends a raw command to the FTP server.
201 */
202 private void sendLine(String line) throws IOException {
203 if (socket == null ) {
204 throw new IOException( " SimpleFTP is not connected. " );
205 }
206 try {
207 writer.write(line + " \r\n " );
208 writer.flush();
209 if (DEBUG) {
210 System.out.println( " > " + line);
211 }
212 } catch (IOException e) {
213 socket = null ;
214 throw e;
215 }
216 }
217
218 private String readLine() throws IOException {
219 String line = reader.readLine();
220 if (DEBUG) {
221 System.out.println( " < " + line);
222 }
223 return line;
224 }
225
226 private Socket socket = null ;
227
228 private BufferedReader reader = null ;
229
230 private BufferedWriter writer = null ;
231
232 private static boolean DEBUG = true ;
233
234
235 // add by wanglinag 2010 9 2
236 public synchronized boolean get(String filename,String savename)
237 throws IOException {
238 Socket dataSocket = getConnection();
239 sendLine( " RETR " + filename);
240 String response = readLine();
241 if ( ! response.startsWith( " 150 " )) {
242 // if (!response.startsWith("150 ")) {
243 throw new IOException(
244 " SimpleFTP was not allowed to get the file: " + response);
245 }
246 FileOutputStream outfile = context.openFileOutput(savename,Context.MODE_WORLD_READABLE);
247 // 构造传输文件用的数据流
248 BufferedInputStream dataInput = new BufferedInputStream(dataSocket.getInputStream());
249 // 接收来自服务器的数据,写入本地文件
250 int n;
251 byte [] buff = new byte [ 1024 ];
252 while ((n = dataInput.read(buff)) > 0 ) {
253 outfile.write(buff, 0 , n);
254 }
255 dataSocket.close();
256 outfile.close();
257
258 response = readLine();
259 return response.startsWith( " 226 " );
260 }
261
262
263 public synchronized Vector < String > List() throws IOException{
264 Socket dataSocket = getConnection();
265 sendLine( " LIST " );
266 Vector < String > result = new Vector < String > ();
267 int n;
268 byte [] buff = new byte [ 65530 ];
269 // 准备读取数据用的流
270 BufferedInputStream dataInput = new BufferedInputStream(dataSocket
271 .getInputStream());
272 // 读取目录信息
273
274 while ((n = dataInput.read(buff)) > 0 ) {
275 System.out.write(buff, 0 , n);
276 result.add( new String(buff, 0 ,n));
277 }
278 dataSocket.close();
279 readLine();
280 readLine();
281
282 return result;
283 }
284
285
286 private Socket getConnection() throws IOException{
287 sendLine( " PASV " );
288 String response = readLine();
289 if ( ! response.startsWith( " 227 " )) {
290 throw new IOException( " SimpleFTP could not request passive mode: "
291 + response);
292 }
293
294 String ip = null ;
295 int port = - 1 ;
296 int opening = response.indexOf( ' ( ' );
297 int closing = response.indexOf( ' ) ' , opening + 1 );
298 if (closing > 0 ) {
299 String dataLink = response.substring(opening + 1 , closing);
300 StringTokenizer tokenizer = new StringTokenizer(dataLink, " , " );
301 try {
302 ip = tokenizer.nextToken() + " . " + tokenizer.nextToken() + " . "
303 + tokenizer.nextToken() + " . " + tokenizer.nextToken();
304 port = Integer.parseInt(tokenizer.nextToken()) * 256
305 + Integer.parseInt(tokenizer.nextToken());
306 } catch (Exception e) {
307 throw new IOException(
308 " SimpleFTP received bad data link information: "
309 + response);
310 }
311 }
312 Socket dataSocket = new Socket(ip, port);
313 return dataSocket;
314 }
315 }
316