FTP客戶端(利用sun.net.ftp.FtpClient實現)

     昨天幫同事弄java上傳文件到ftp服務器,用的sun.net.ftp.FtpClient,感覺很簡單,也很好用,寫了個小例子,留作備份。

     這個小例子實現了文件(或文件夾)上傳,文件下載,取得某目錄下文件列表等功能,對於文件夾下載還沒有實現,改天有空改完了再貼上來吧。由於通過設定好的用戶名、密碼登陸到ftp server時,連接到的目錄不一定是根目錄,有可能是根目錄下很深層的一個子目錄,比如“usr/why/test/ftp/upload/exercise/20090730”,所以我覺得針對當前連接目錄進行操作,要比每次都從根目錄開始指定方便。
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import sun.net.TelnetInputStream;
import sun.net.TelnetOutputStream;
import sun.net.ftp.FtpClient;

public class FTPUtil{        

        private String ip = "";        

        private String username = "";        

        private String password = "";        

        private int port = -1;        

        private String path = "";        

        FtpClient ftpClient = null;        

        OutputStream os = null;        

        FileInputStream is = null;        

        public FtpUtil(String serverIP, String username, String password) {        
                this.ip = serverIP;        
                this.username = username;        
                this.password = password;        
        }        
                
        public FtpUtil(String serverIP, int port, String username, String password) {        
                this.ip = serverIP;        
                this.username = username;        
                this.password = password;        
                this.port = port;        
        }        

        /**    
         * 連接ftp服務器    
         *        
         * @throws IOException    
         */
    
        public boolean connectServer(){        
                ftpClient = new FtpClient();        
                try {        
                        if(this.port != -1){        
                                        ftpClient.openServer(this.ip,this.port);        
                        }else{        
                                ftpClient.openServer(this.ip);        
                        }        
                        ftpClient.login(this.username, this.password);        
                        if (this.path.length() != 0){        
                                ftpClient.cd(this.path);// path是ftp服務下主目錄的子目錄                            
                        }        
                        ftpClient.binary();// 用2進制上傳、下載        
                        System.out.println("已登錄到\"" + ftpClient.pwd() + "\"目錄");        
                        return true;        
                }catch (IOException e){        
                        e.printStackTrace();        
                        return false;        
                }        
        }        
                
        /**    
         * 斷開與ftp服務器連接    
         *        
         * @throws IOException    
         */
    
        public boolean closeServer(){        
                try{        
                        if (is != null) {        
                                is.close();        
                        }        
                        if (os != null) {        
                                os.close();        
                        }        
                        if (ftpClient != null) {        
                                ftpClient.closeServer();        
                        }        
                        System.out.println("已從服務器斷開");        
                        return true;        
                }catch(IOException e){        
                        e.printStackTrace();        
                        return false;        
                }        
        }        
                
        /**    
         * 檢查文件夾在當前目錄下是否存在    
         * @param dir    
         * @return    
         */
    
         private boolean isDirExist(String dir){        
                 String pwd = "";        
                 try {        
                         pwd = ftpClient.pwd();        
                         ftpClient.cd(dir);        
                         ftpClient.cd(pwd);        
                 }catch(Exception e){        
                         return false;        
                 }        
                 return true;        
         }        
                
        /**    
         * 在當前目錄下創建文件夾    
         * @param dir    
         * @return    
         * @throws Exception    
         */
    
         private boolean createDir(String dir){        
                 try{        
                        ftpClient.ascii();        
                        StringTokenizer s = new StringTokenizer(dir, "/"); //sign        
                        s.countTokens();        
                        String pathName = ftpClient.pwd();        
                        while(s.hasMoreElements()){        
                                pathName = pathName + "/" + (String) s.nextElement();        
                                try {        
                                        ftpClient.sendServer("MKD " + pathName + "\r\n");        
                                } catch (Exception e) {        
                                        e = null;        
                                        return false;        
                                }        
                                ftpClient.readServerResponse();        
                        }        
                        ftpClient.binary();        
                        return true;        
                }catch (IOException e1){        
                        e1.printStackTrace();        
                        return false;        
                }        
         }        
                
         /**    
            * ftp上傳    
            * 如果服務器段已存在名爲filename的文件夾,該文件夾中與要上傳的文件夾中同名的文件將被替換    
            *        
            * @param filename 要上傳的文件(或文件夾)名    
            * @return    
            * @throws Exception    
            */
    
        public boolean upload(String filename){        
                String newname = "";        
                if(filename.indexOf("/") > -1){        
                        newname = filename.substring(filename.lastIndexOf("/") + 1);        
                }else{        
                        newname = filename;        
                }        
                return upload(filename, newname);        
        }        
                
         /**    
            * ftp上傳    
            * 如果服務器段已存在名爲newName的文件夾,該文件夾中與要上傳的文件夾中同名的文件將被替換    
            *        
            * @param fileName 要上傳的文件(或文件夾)名    
            * @param newName 服務器段要生成的文件(或文件夾)名    
            * @return    
            */
    
         public boolean upload(String fileName, String newName){        
                 try{        
                         String savefilename = new String(fileName.getBytes("ISO-8859-1"), "GBK");        
                         File file_in = new File(savefilename);//打開本地待長傳的文件        
                         if(!file_in.exists()){        
                                 throw new Exception("此文件或文件夾[" + file_in.getName() + "]有誤或不存在!");        
                         }        
                         if(file_in.isDirectory()){        
                                 upload(file_in.getPath(),newName,ftpClient.pwd());        
                         }else{        
                                 uploadFile(file_in.getPath(),newName);        
                         }        
                                
                         if(is != null){        
                                 is.close();        
                         }        
                         if(os != null){        
                                 os.close();        
                         }        
                         return true;        
                 }catch(Exception e){        
                                e.printStackTrace();        
                                System.err.println("Exception e in Ftp upload(): " + e.toString());        
                                return false;        
                 }finally{        
                         try{        
                                 if(is != null){        
                                         is.close();        
                                 }        
                                 if(os != null){        
                                         os.close();        
                                 }        
                         }catch(IOException e){        
                                 e.printStackTrace();        
                        }        
                 }        
         }        
                
         /**    
            * 真正用於上傳的方法    
            * @param fileName    
            * @param newName    
            * @param path    
            * @throws Exception    
            */
    
         private void upload(String fileName, String newName,String path) throws Exception{        
                         String savefilename = new String(fileName.getBytes("ISO-8859-1"), "GBK");        
                         File file_in = new File(savefilename);//打開本地待長傳的文件        
                         if(!file_in.exists()){        
                                 throw new Exception("此文件或文件夾[" + file_in.getName() + "]有誤或不存在!");        
                         }        
                         if(file_in.isDirectory()){        
                                 if(!isDirExist(newName)){        
                                         createDir(newName);        
                                 }        
                                 ftpClient.cd(newName);        
                                 File sourceFile[] = file_in.listFiles();        
                                 for(int i = 0; i < sourceFile.length; i++){        
                                         if(!sourceFile[i].exists()){        
                                                 continue;        
                                         }        
                                         if(sourceFile[i].isDirectory()){        
                                                 this.upload(sourceFile[i].getPath(),sourceFile[i].getName(),path+"/"+newName);        
                                         }else{        
                                                 this.uploadFile(sourceFile[i].getPath(),sourceFile[i].getName());        
                                            }        
                                        }        
                         }else{        
                                 uploadFile(file_in.getPath(),newName);        
                         }        
                         ftpClient.cd(path);        
         }        

        /**    
         * upload 上傳文件    
         *        
         * @param filename 要上傳的文件名    
         * @param newname 上傳後的新文件名    
         * @return -1 文件不存在 >=0 成功上傳,返回文件的大小    
         * @throws Exception    
         */
    
        public long uploadFile(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;        
                        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;        
        }        

        /**    
         * 從ftp下載文件到本地    
         *        
         * @param filename 服務器上的文件名    
         * @param newfilename 本地生成的文件名    
         * @return    
         * @throws Exception    
         */
    
        public long downloadFile(String filename, String newfilename){        
                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{        
                        try {        
                                if(is != null){        
                                                is.close();        
                                }        
                                if(os != null){        
                                        os.close();        
                                }        
                        } catch (IOException e) {        
                                e.printStackTrace();        
                        }        
                }        
                return result;        
        }        

        /**    
         * 取得相對於當前連接目錄的某個目錄下所有文件列表    
         *        
         * @param path    
         * @return    
         */
    
        public List getFileList(String path){        
                List list = new ArrayList();        
                DataInputStream dis;        
                try {        
                        dis = new DataInputStream(ftpClient.nameList(this.path + path));        
                        String filename = "";        
                        while((filename = dis.readLine()) != null){        
                                list.add(filename);        
                        }        
                } catch (IOException e) {        
                        e.printStackTrace();        
                }        
                return list;        
        }        

                

        public static void main(String[] args){        
                FtpUtil ftp = new FtpUtil("133.224.202.2","tstbill","tstbill");        
                ftp.connectServer();        
                boolean result = ftp.upload("C:/test_why", "test_why/test");        
                System.out.println(result?"上傳成功!":"上傳失敗!");        
                List list = ftp.getFileList("test_why/test");        
                for(int i=0;i<list.size();i++){        
                        String name = list.get(i).toString();        
                        System.out.println(name);        
                }        
                ftp.closeServer();        
                /**    
                FTP遠程命令列表    
                USER        PORT        RETR        ALLO        DELE        SITE        XMKD        CDUP        FEAT    
                PASS        PASV        STOR        REST        CWD         STAT        RMD         XCUP        OPTS    
                ACCT        TYPE        APPE        RNFR        XCWD        HELP        XRMD        STOU        AUTH    
                REIN        STRU        SMNT        RNTO        LIST        NOOP        PWD         SIZE        PBSZ    
                QUIT        MODE        SYST        ABOR        NLST        MKD         XPWD        MDTM        PROT    
                在服務器上執行命令,如果用sendServer來執行遠程命令(不能執行本地FTP命令)的話,所有FTP命令都要加上\r\n    
                ftpclient.sendServer("XMKD /test/bb\r\n"); //執行服務器上的FTP命令    
                ftpclient.readServerResponse一定要在sendServer後調用    
                nameList("/test")獲取指目錄下的文件列表    
                XMKD建立目錄,當目錄存在的情況下再次創建目錄時報錯    
                XRMD刪除目錄    
                DELE刪除文件    
                 */
    
        }        

}    
 
 
下面是FtpClient類的一些介紹:

sun.net.ftp.FtpClient.,該類庫主要提供了用於建立FTP連接的類。利用這些類的方法,編程人員可以遠程登錄到FTP服務器,列舉該服務器上的目錄,設置傳輸協議,以及傳送文件。FtpClient類涵蓋了幾乎所有FTP的功能,FtpClient的實例變量保存了有關建立"代理"的各種信息。下面給出了這些實例變量:
  public static boolean useFtpProxy
   這個變量用於表明FTP傳輸過程中是否使用了一個代理,因此,它實際上是一個標記,此標記若爲TRUE,表明使用了一個代理主機。

  public static String ftpProxyHost
   此變量只有在變量useFtpProxy爲TRUE時纔有效,用於保存代理主機名。

  public static int ftpProxyPort
   此變量只有在變量useFtpProxy爲TRUE時纔有效,用於保存代理主機的端口地址。

  FtpClient有三種不同形式的構造函數,如下所示:
  1、public FtpClient(String hostname,int port)
    此構造函數利用給出的主機名和端口號建立一條FTP連接。

  2、public FtpClient(String hostname)
   此構造函數利用給出的主機名建立一條FTP連接,使用默認端口號。

  3、FtpClient()
   此構造函數將創建一FtpClient類,但不建立FTP連接。這時,FTP連接可以用openServer方法建立。

  一旦建立了類FtpClient,就可以用這個類的方法來打開與FTP服務器的連接。類ftpClient提供瞭如下兩個可用於打開與FTP服務器之間的連接的方法。
  public void openServer(String hostname)
   這個方法用於建立一條與指定主機上的FTP服務器的連接,使用默認端口號。

  public void openServer(String host,int port)
   這個方法用於建立一條與指定主機、指定端口上的FTP服務器的連接。

  打開連接之後,接下來的工作是註冊到FTP服務器。這時需要利用下面的方法。
  public void login(String username,String password)
   此方法利用參數username和password登錄到FTP服務器。使用過Intemet的用戶應該知道,匿名FTP服務器的登錄用戶名爲anonymous,密碼一般用自己的電子郵件地址。

  下面是FtpClient類所提供的一些控制命令。
  public void cd(String remoteDirectory):該命令用於把遠程系統上的目錄切換到參數remoteDirectory所指定的目錄。
   public void cdUp():該命令用於把遠程系統上的目錄切換到上一級目錄。
   public String pwd():該命令可顯示遠程系統上的目錄狀態。
   public void binary():該命令可把傳輸格式設置爲二進制格式。
   public void ascii():該命令可把傳輸協議設置爲ASCII碼格式。
   public void rename(String string,String string1):該命令可對遠程系統上的目錄或者文件進行重命名操作。

  除了上述方法外,類FtpClient還提供了可用於傳遞並檢索目錄清單和文件的若干方法。這些方法返回的是可供讀或寫的輸入、輸出流。下面是其中一些主要的方法。
  public TelnetInputStream list()
   返回與遠程機器上當前目錄相對應的輸入流。

  public TelnetInputStream get(String filename)
   獲取遠程機器上的文件filename,藉助TelnetInputStream把該文件傳送到本地。

  public TelnetOutputStream put(String filename)
   以寫方式打開一輸出流,通過這一輸出流把文件filename傳送到遠程計算機。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章