FTPClient使用教程

lvwmj 贡献于2011-05-18

作者 番茄花园  创建于2011-04-28 14:33:00   修改者番茄花园  修改于2011-04-28 16:10:00字数12029

文档摘要:在JAVA程序中,经常需要和FTP打交道,比如向FTP服务器上传文件、下载文件,本文简单介绍如何利用jakartacommons中的FTPClient(在commons-net包中)实现上传下载文件。
关键词:

在JAVA程序中,经常需要和FTP打交道,比如向FTP服务器上传文件、下载文件,本文简单介绍如何利用jakarta commons中的FTPClient(在commons-net包中)实现上传下载文件。  一、上传文件           原理就不介绍了,大家直接看代码吧  view plaincopy to clipboardprint?     1. /**     2.  * Description: 向FTP服务器上传文件     3.  * @Version1.0 Jul 27, 2008 4:31:09 PM by 崔红保(cuihongbao@d-heaven.com)创建     4.  * @param url FTP服务器hostname     5.  * @param port FTP服务器端口     6.  * @param username FTP登录账号     7.  * @param password FTP登录密码     8.  * @param path FTP服务器保存目录     9.  * @param filename 上传到FTP服务器上的文件名    10.  * @param input 输入流    11.  * @return 成功返回true,否则返回false    12.  */     13. public static boolean uploadFile(String url,int port,String username, String password, String path, String filename, InputStream input) {     14.     boolean success = false;     15.     FTPClient ftp = new FTPClient();     16.     try {     17.         int reply;     18.         ftp.connect(url, port);//连接FTP服务器     19.         //如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器     20.         ftp.login(username, password);//登录     21.         reply = ftp.getReplyCode();     22.         if (!FTPReply.isPositiveCompletion(reply)) {     23.             ftp.disconnect();     24.             return success;     25.         }     26.         ftp.changeWorkingDirectory(path);     27.         ftp.storeFile(filename, input);              28.              29.         input.close();     30.         ftp.logout();     31.         success = true;     32.     } catch (IOException e) {     33.         e.printStackTrace();     34.     } finally {     35.         if (ftp.isConnected()) {     36.             try {     37.                 ftp.disconnect();     38.             } catch (IOException ioe) {     39.             }     40.         }     41.     }     42.     return success;     43. }
      /**   * Description: 向FTP服务器上传文件   * @Version1.0 Jul 27, 2008 4:31:09 PM by 崔红保(cuihongbao@d-heaven.com)创建   * @param url FTP服务器hostname   * @param port FTP服务器端口   * @param username FTP登录账号   * @param password FTP登录密码   * @param path FTP服务器保存目录   * @param filename 上传到FTP服务器上的文件名   * @param input 输入流   * @return 成功返回true,否则返回false   */   public static boolean uploadFile(String url,int port,String username, String password, String path, String filename, InputStream input) {   boolean success = false;   FTPClient ftp = new FTPClient();   try {   int reply;   ftp.connect(url, port);//连接FTP服务器   //如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器   ftp.login(username, password);//登录   reply = ftp.getReplyCode();   if (!FTPReply.isPositiveCompletion(reply)) {   ftp.disconnect();   return success;   }   ftp.changeWorkingDirectory(path);   ftp.storeFile(filename, input);     input.close();   ftp.logout();   success = true;   } catch (IOException e) {   e.printStackTrace();   } finally {     if (ftp.isConnected()) {   try {   ftp.disconnect();   } catch (IOException ioe) {   }   }   }   return success;   }         下面我们写两个小例子:     1.将本地文件上传到FTP服务器上,代码如下:   view plaincopy to clipboardprint?        1. @Test       2. public void testUpLoadFromDisk(){       3.     try {       4.         FileInputStream in=new FileInputStream(new File("D:/test.txt"));       5.         boolean flag = uploadFile("127.0.0.1", 21, "test", "test", "D:/ftp", "test.txt", in);       6.         System.out.println(flag);       7.     } catch (FileNotFoundException e) {       8.         e.printStackTrace();       9.     }      10. }
      @Test   public void testUpLoadFromDisk(){   try {   FileInputStream in=new FileInputStream(new File("D:/test.txt"));   boolean flag = uploadFile("127.0.0.1", 21, "test", "test", "D:/ftp", "test.txt", in);   System.out.println(flag);   } catch (FileNotFoundException e) {   e.printStackTrace();   }   }     2.在FTP服务器上生成一个文件,并将一个字符串写入到该文件中   view plaincopy to clipboardprint?        1. @Test       2. public void testUpLoadFromString(){         3.     try {       4.         InputStream input = new ByteArrayInputStream("test ftp".getBytes("utf-8"));       5.         boolean flag = uploadFile("127.0.0.1", 21, "test", "test", "D:/ftp", "test.txt", input);       6.         System.out.println(flag);       7.     } catch (UnsupportedEncodingException e) {       8.         e.printStackTrace();       9.     }      10. }
      @Test   public void testUpLoadFromString(){   try {   InputStream input = new ByteArrayInputStream("test ftp".getBytes("utf-8"));   boolean flag = uploadFile("127.0.0.1", 21, "test", "test", "D:/ftp", "test.txt", input);   System.out.println(flag);   } catch (UnsupportedEncodingException e) {   e.printStackTrace();   }   }       二、下载文件            从FTP服务器下载文件的代码也很简单,参考如下:   view plaincopy to clipboardprint?        1. /**      2.  * Description: 从FTP服务器下载文件      3.  * @Version1.0 Jul 27, 2008 5:32:36 PM by 崔红保(cuihongbao@d-heaven.com)创建      4.  * @param url FTP服务器hostname      5.  * @param port FTP服务器端口      6.  * @param username FTP登录账号      7.  * @param password FTP登录密码      8.  * @param remotePath FTP服务器上的相对路径      9.  * @param fileName 要下载的文件名     10.  * @param localPath 下载后保存到本地的路径     11.  * @return     12.  */      13. public static boolean downFile(String url, int port,String username, String password, String remotePath,String fileName,String localPath) {      14.     boolean success = false;      15.     FTPClient ftp = new FTPClient();      16.     try {      17.         int reply;        18.         ftp.connect(url, port);      19.         //如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器      20.         ftp.login(username, password);//登录      21.         reply = ftp.getReplyCode();      22.         if (!FTPReply.isPositiveCompletion(reply)) {      23.             ftp.disconnect();      24.             return success;      25.         }      26.         ftp.changeWorkingDirectory(remotePath);//转移到FTP服务器目录      27.         FTPFile[] fs = ftp.listFiles();      28.         for(FTPFile ff:fs){      29.             if(ff.getName().equals(fileName)){      30.                 File localFile = new File(localPath+"/"+ff.getName());      31.                       32.                 OutputStream is = new FileOutputStream(localFile);       33.                 ftp.retrieveFile(ff.getName(), is);      34.                 is.close();      35.             }      36.         }      37.               38.         ftp.logout();      39.         success = true;      40.     } catch (IOException e) {      41.         e.printStackTrace();      42.     } finally {      43.         if (ftp.isConnected()) {      44.             try {      45.                 ftp.disconnect();      46.             } catch (IOException ioe) {      47.             }      48.         }      49.     }      50.     return success;                    要用到的jar:  1.commons-io-1.4.jar  2.commons-net-1.4.1.jar  3.commons-pool-1.3.jar  4.jakarta-oro-2.0.8.jar  import java.io.File;  import java.io.IOException;  import java.io.FileOutputStream;  import java.io.InputStream;  import java.io.OutputStream;  import java.io.RandomAccessFile;  import org.apache.commons.net.ftp.FTP;  import org.apache.commons.net.ftp.FTPClient;  import org.apache.commons.net.ftp.FTPFile;  import org.apache.commons.net.ftp.FTPReply;  public class FtpHelper {  private FTPClient ftpClient = new FTPClient();     /**         * 连接到FTP服务器         * @param hostname 主机名         * @param port 端口         * @param username 用户名         * @param password 密码         * @return 是否连接成功         * @throws IOException         */        public boolean connect(String hostname,int port,String username,String password) throws IOException{              ftpClient.connect(hostname, port);              ftpClient.setControlEncoding("GBK");              if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){                  if(ftpClient.login(username, password)){                      return true;                  }              }              disconnect();              return false;          }                    /**         * 从FTP服务器上下载文件,支持断点续传,上传百分比汇报         * @param remote 远程文件路径           * @param local 本地文件路径         * @return 上传的状态         * @throws IOException         */        public DownloadStatus download(String remote,String local) throws IOException{              //设置被动模式              ftpClient.enterLocalPassiveMode();              //设置以二进制方式传输              ftpClient.setFileType(FTP.BINARY_FILE_TYPE);              DownloadStatus result;                            //检查远程文件是否存在              FTPFile[] files = ftpClient.listFiles(new String(remote.getBytes("GBK"),"iso-8859-1"));              if(files.length != 1){                  System.out.println("远程文件不存在");                  return DownloadStatus.Remote_File_Noexist;              }                            long lRemoteSize = files[0].getSize();              File f = new File(local);              //本地存在文件,进行断点下载              if(f.exists()){                  long localSize = f.length();                  //判断本地文件大小是否大于远程文件大小                  if(localSize >= lRemoteSize){                      System.out.println("本地文件大于远程文件,下载中止");                      return DownloadStatus.Local_Bigger_Remote;                  }                                    //进行断点续传,并记录状态                  FileOutputStream out = new FileOutputStream(f,true);                  ftpClient.setRestartOffset(localSize);                  InputStream in = ftpClient.retrieveFileStream(new String(remote.getBytes("GBK"),"iso-8859-1"));                  byte[] bytes = new byte[1024];                  long step = lRemoteSize /100;                  long process=localSize /step;                  int c;                  while((c = in.read(bytes))!= -1){                      out.write(bytes,0,c);                      localSize+=c;                      long nowProcess = localSize /step;                      if(nowProcess > process){                          process = nowProcess;                            if(process % 10 == 0)                              System.out.println("下载进度:"+process);                          //TODO 更新文件下载进度,值存放在process变量中                      }                  }                  in.close();                  out.close();                  boolean isDo = ftpClient.completePendingCommand();                  if(isDo){                      result = DownloadStatus.Download_From_Break_Success;                  }else {                      result = DownloadStatus.Download_From_Break_Failed;                  }              }else {                  OutputStream out = new FileOutputStream(f);                  InputStream in= ftpClient.retrieveFileStream(new String(remote.getBytes("GBK"),"iso-8859-1"));                  byte[] bytes = new byte[1024];                  long step = lRemoteSize /100;                  long process=0;                  long localSize = 0L;                  int c;                  while((c = in.read(bytes))!= -1){                      out.write(bytes, 0, c);                      localSize+=c;                      long nowProcess = localSize /step;                      if(nowProcess > process){                          process = nowProcess;                          if(process % 10 == 0)                              System.out.println("下载进度:"+process);                          //TODO 更新文件下载进度,值存放在process变量中                      }                  }                  in.close();                  out.close();                  boolean upNewStatus = ftpClient.completePendingCommand();                  if(upNewStatus){                      result = DownloadStatus.Download_New_Success;                  }else {                      result = DownloadStatus.Download_New_Failed;                  }              }              return result;          }                      /**         * 上传文件到FTP服务器,支持断点续传         * @param local 本地文件名称,绝对路径         * @param remote 远程文件路径,使用/home/directory1/subdirectory/file.ext 按照Linux上的路径指定方式,支持多级目录嵌套,支持递归创建不存在的目录结构         * @return 上传结果         * @throws IOException         */        public UploadStatus upload(String local,String remote) throws IOException{              //设置PassiveMode传输              ftpClient.enterLocalPassiveMode();              //设置以二进制流的方式传输              ftpClient.setFileType(FTP.BINARY_FILE_TYPE);              ftpClient.setControlEncoding("GBK");              UploadStatus result;              //对远程目录的处理              String remoteFileName = remote;              if(remote.contains("/")){                  remoteFileName = remote.substring(remote.lastIndexOf("/")+1);                  //创建服务器远程目录结构,创建失败直接返回                  if(createDirecroty(remote, ftpClient)==UploadStatus.Create_Directory_Fail){                      return UploadStatus.Create_Directory_Fail;                  }              }                            //检查远程是否存在文件              FTPFile[] files = ftpClient.listFiles(new String(remoteFileName.getBytes("GBK"),"iso-8859-1"));              if(files.length == 1){                  long remoteSize = files[0].getSize();                  File f = new File(local);                  long localSize = f.length();                  if(remoteSize==localSize){   //文件存在                   return UploadStatus.File_Exits;                  }else if(remoteSize > localSize){                      return UploadStatus.Remote_Bigger_Local;                  }                                    //尝试移动文件内读取指针,实现断点续传                  result = uploadFile(remoteFileName, f, ftpClient, remoteSize);                                    //如果断点续传没有成功,则删除服务器上文件,重新上传                  if(result == UploadStatus.Upload_From_Break_Failed){                        if(!ftpClient.deleteFile(remoteFileName)){                          return UploadStatus.Delete_Remote_Faild;                      }                      result = uploadFile(remoteFileName, f, ftpClient, 0);                  }              }else {                  result = uploadFile(remoteFileName, new File(local), ftpClient, 0);              }              return result;          }          /**         * 断开与远程服务器的连接         * @throws IOException         */        public void disconnect() throws IOException{              if(ftpClient.isConnected()){                  ftpClient.disconnect();              }          }                    /**         * 递归创建远程服务器目录         * @param remote 远程服务器文件绝对路径         * @param ftpClient FTPClient对象         * @return 目录创建是否成功         * @throws IOException         */        public UploadStatus createDirecroty(String remote,FTPClient ftpClient) throws IOException{              UploadStatus status = UploadStatus.Create_Directory_Success;              String directory = remote.substring(0,remote.lastIndexOf("/")+1);              if(!directory.equalsIgnoreCase("/")&&!ftpClient.changeWorkingDirectory(new String(directory.getBytes("GBK"),"iso-8859-1"))){                  //如果远程目录不存在,则递归创建远程服务器目录                  int start=0;                  int end = 0;                  if(directory.startsWith("/")){                      start = 1;                  }else{                      start = 0;                  }                  end = directory.indexOf("/",start);                  while(true){                      String subDirectory = new String(remote.substring(start,end).getBytes("GBK"),"iso-8859-1");                        if(!ftpClient.changeWorkingDirectory(subDirectory)){                          if(ftpClient.makeDirectory(subDirectory)){                              ftpClient.changeWorkingDirectory(subDirectory);                          }else {                              System.out.println("创建目录失败");                              return UploadStatus.Create_Directory_Fail;                          }                      }                                            start = end + 1;                      end = directory.indexOf("/",start);                                            //检查所有目录是否创建完毕                      if(end <= start){                          break;                      }                  }              }              return status;          }                    /**         * 上传文件到服务器,新上传和断点续传         * @param remoteFile 远程文件名,在上传之前已经将服务器工作目录做了改变         * @param localFile 本地文件File句柄,绝对路径         * @param processStep 需要显示的处理进度步进值         * @param ftpClient FTPClient引用         * @return         * @throws IOException         */        public UploadStatus uploadFile(String remoteFile,File localFile,FTPClient ftpClient,long remoteSize) throws IOException{              UploadStatus status;              //显示进度的上传              long step = localFile.length() / 100;              long process = 0;              long localreadbytes = 0L;              RandomAccessFile raf = new RandomAccessFile(localFile,"r");              OutputStream out = ftpClient.appendFileStream(new String(remoteFile.getBytes("GBK"),"iso-8859-1"));              //断点续传              if(remoteSize>0){                  ftpClient.setRestartOffset(remoteSize);                  process = remoteSize /step;                    raf.seek(remoteSize);                  localreadbytes = remoteSize;              }              byte[] bytes = new byte[1024];              int c;              while((c = raf.read(bytes))!= -1){                  out.write(bytes,0,c);                  localreadbytes+=c;                  if(localreadbytes / step != process){                      process = localreadbytes / step;                      System.out.println("上传进度:" + process);                      //TODO 汇报上传状态                                                                           }              }              out.flush();              raf.close();              out.close();              boolean result =ftpClient.completePendingCommand();              if(remoteSize > 0){                  status = result?UploadStatus.Upload_From_Break_Success:UploadStatus.Upload_From_Break_Failed;              }else {                  status = result?UploadStatus.Upload_New_File_Success:UploadStatus.Upload_New_File_Failed;              }              return status;          }                 public static void main(String[] args) {        FtpHelper myFtp = new FtpHelper();              try {                  myFtp.connect("192.168.1.166", 21, "test", "test");             System.out.println(myFtp.upload("d:/test/信息反馈.txt","/信息反馈.txt"));                 myFtp.disconnect();              } catch (IOException e) {                              System.out.println("连接FTP出错:"+e.getMessage());                  e.printStackTrace();           }    }           public enum UploadStatus {             Create_Directory_Fail,      //远程服务器相应目录创建失败             Create_Directory_Success,   //远程服务器闯将目录成功             Upload_New_File_Success,    //上传新文件成功             Upload_New_File_Failed,     //上传新文件失败             File_Exits,                 //文件已经存在             Remote_Bigger_Local,        //远程文件大于本地文件             Upload_From_Break_Success, //断点续传成功             Upload_From_Break_Failed,   //断点续传失败             Delete_Remote_Faild;        //删除远程文件失败         }            public enum DownloadStatus {          Remote_File_Noexist, //远程文件不存在             Download_New_Success,    //下载文件成功             Download_New_Failed,     //下载文件失败              Local_Bigger_Remote,        //本地文件大于远程文件          Download_From_Break_Success, //断点续传成功             Download_From_Break_Failed;   //断点续传失败         }   }  

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享文档获得金币 ] 6 人已下载

下载文档