littlefermat

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 

posted on 2010-09-03 11:39 littlefermat 阅读(1358) 评论(1)  编辑  收藏

Feedback

# re: socket实现的ftp 被动式下载(android平台) 2011-12-12 14:23 ERP

HAO  回复  更多评论   



只有注册用户登录后才能发表评论。


网站导航: