分享

Apache FTP多线程文件上传、下载、修改文件名、删除

 心不留意外尘 2016-07-17

http://blog.csdn.net/boonya/article/details/24422299

2014

请参考上一篇章:Apache FTP文件上传、下载、修改文件名、删除

此处实现多线程对FTP文件的操作,FTPStatus来自上一篇文章,下附工具代码。

  1. package com.scengine.wtms.utils.ftp;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileOutputStream;  
  6. import java.io.IOException;  
  7. import java.io.InputStream;  
  8. import java.io.OutputStream;  
  9. import java.io.PrintWriter;  
  10. import java.net.SocketException;  
  11.   
  12. import javax.servlet.http.HttpServletResponse;  
  13.   
  14. import org.apache.commons.net.PrintCommandListener;  
  15. import org.apache.commons.net.ftp.FTP;  
  16. import org.apache.commons.net.ftp.FTPClient;  
  17. import org.apache.commons.net.ftp.FTPFile;  
  18. import org.apache.commons.net.ftp.FTPReply;  
  19.   
  20. import com.scengine.wtms.utils.Log;  
  21.   
  22. public class ThreadFTPUtils  implements Runnable  
  23. {  
  24.     private UserInfo userInfo;  
  25.       
  26.     private FTPClient ftpClient = new FTPClient();  
  27.       
  28.     private FTPType ftpType;  
  29.       
  30.     public FTPType getFtpType()  
  31.     {  
  32.         return ftpType;  
  33.     }  
  34.   
  35.     public void setFtpType(FTPType ftpType)  
  36.     {  
  37.         this.ftpType = ftpType;  
  38.     }  
  39.   
  40.     public static enum FTPType{  
  41.           
  42.         UPLOAD(0),DOWNLOAD(1),RENAME(2),DELETE(3);  
  43.           
  44.         private int type;  
  45.           
  46.         public int getType()  
  47.         {  
  48.             return type;  
  49.         }  
  50.         public void setType(int type)  
  51.         {  
  52.             this.type = type;  
  53.         }  
  54.         FTPType(int type){  
  55.             this.type=type;  
  56.         }  
  57.     }  
  58.   
  59.   
  60.     /** 
  61.      * 对象构造 设置将过程中使用到的命令输出到控制台 
  62.      */  
  63.     public ThreadFTPUtils(String ip,int port,String username,String password,String local,String remote,FTPType ftpType)  
  64.     {  
  65.         userInfo=new UserInfo(ip, port, username, password, local, remote);  
  66.         this.ftpType=ftpType;  
  67.         this.ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));  
  68.     }  
  69.   
  70.     /** 
  71.      *  
  72.      * java编程中用于连接到FTP服务器 
  73.      *  
  74.      * @param hostname 
  75.      *            主机名 
  76.      *  
  77.      * @param port 
  78.      *            端口 
  79.      *  
  80.      * @param username 
  81.      *            用户名 
  82.      *  
  83.      * @param password 
  84.      *            密码 
  85.      *  
  86.      * @return 是否连接成功 
  87.      *  
  88.      * @throws IOException 
  89.      */  
  90.   
  91.     public boolean connect(String hostname, int port, String username, String password) throws IOException  
  92.     {  
  93.   
  94.         ftpClient.connect(hostname, port);  
  95.   
  96.         if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode()))  
  97.         {  
  98.   
  99.             if (ftpClient.login(username, password))  
  100.             {  
  101.                 return true;  
  102.             }  
  103.         }  
  104.         disconnect();  
  105.         return false;  
  106.     }  
  107.   
  108.     /** 
  109.      * 删除远程FTP文件 
  110.      *  
  111.      * @param remote 
  112.      *            远程文件路径 
  113.      * @return 
  114.      * @throws IOException 
  115.      */  
  116.     public FTPStatus delete(String remote) throws IOException  
  117.     {  
  118.         ftpClient.enterLocalPassiveMode();  
  119.   
  120.         ftpClient.setFileType(FTP.BINARY_FILE_TYPE);  
  121.   
  122.         FTPStatus result = null;  
  123.   
  124.         FTPFile[] files = ftpClient.listFiles(remote);  
  125.         if (files.length == 1)  
  126.         {  
  127.             boolean status = ftpClient.deleteFile(remote);  
  128.             result = status ? FTPStatus.Delete_Remote_Success : FTPStatus.Delete_Remote_Faild;  
  129.         }  
  130.         else  
  131.         {  
  132.             result = FTPStatus.Not_Exist_File;  
  133.         }  
  134.         Log.getLogger(this.getClass()).info("FTP服务器文件删除标识:"+result);  
  135.         return result;  
  136.     }  
  137.       
  138.     /** 
  139.      * 重命名远程FTP文件 
  140.      *  
  141.      * @param name 
  142.      *            新远程文件名称(路径-必须保证在同一路径下) 
  143.      *             
  144.      * @param remote 
  145.      *            远程文件路径 
  146.      *             
  147.      * @return  是否成功 
  148.      *  
  149.      * @throws IOException 
  150.      */  
  151.     public FTPStatus rename(String name,String remote) throws IOException  
  152.     {  
  153.         ftpClient.enterLocalPassiveMode();  
  154.   
  155.         ftpClient.setFileType(FTP.BINARY_FILE_TYPE);  
  156.   
  157.         FTPStatus result = null;  
  158.   
  159.         FTPFile[] files = ftpClient.listFiles(remote);  
  160.         if (files.length == 1)  
  161.         {  
  162.             boolean status = ftpClient.rename(remote, name);  
  163.             result = status ? FTPStatus.Remote_Rename_Success : FTPStatus.Remote_Rename_Faild;  
  164.         }  
  165.         else  
  166.         {  
  167.             result = FTPStatus.Not_Exist_File;  
  168.         }  
  169.         Log.getLogger(this.getClass()).info("FTP服务器文件名更新标识:"+result);  
  170.         return result;  
  171.     }  
  172.       
  173.     /** 
  174.      *  
  175.      * 从FTP服务器上下载文件 
  176.      *  
  177.      * @param fileName 
  178.      *            下载文件的名字(包括后缀名) 
  179.      *  
  180.      * @param remote 
  181.      *            远程文件路径 
  182.      *  
  183.      * @param local 
  184.      *            本地文件路径 
  185.      *  
  186.      * @return 是否成功 
  187.      *  
  188.      * @throws IOException 
  189.      */  
  190.   
  191.     public FTPStatus download(String fileName,String remote,HttpServletResponse response) throws IOException  
  192.     {  
  193.         // 开启输出流弹出文件保存路径选择窗口  
  194.         response.setContentType("application/octet-stream");  
  195.           
  196.         response.setContentType("application/OCTET-STREAM;charset=UTF-8");  
  197.           
  198.         response.setHeader("Content-Disposition", "attachment;filename=" +fileName);  
  199.   
  200.         ftpClient.enterLocalPassiveMode();  
  201.   
  202.         ftpClient.setFileType(FTP.BINARY_FILE_TYPE);  
  203.           
  204.         FTPStatus result;  
  205.           
  206.         OutputStream out = response.getOutputStream();  
  207.           
  208.         boolean status = ftpClient.retrieveFile(remote, out);  
  209.           
  210.         result=status?FTPStatus.Download_From_Break_Success:FTPStatus.Download_From_Break_Faild;  
  211.           
  212.         Log.getLogger(this.getClass()).info("FTP服务器文件下载标识:"+result);  
  213.           
  214.         out.close();  
  215.           
  216.         return result;  
  217.     }  
  218.   
  219.     /** 
  220.      *  
  221.      * 从FTP服务器上下载文件 
  222.      *  
  223.      * @param remote 
  224.      *            远程文件路径 
  225.      *  
  226.      * @param local 
  227.      *            本地文件路径 
  228.      *  
  229.      * @return 是否成功 
  230.      *  
  231.      * @throws IOException 
  232.      */  
  233.   
  234.     @SuppressWarnings("resource")  
  235.     public FTPStatus download(String remote, String local) throws IOException  
  236.     {  
  237.   
  238.         ftpClient.enterLocalPassiveMode();  
  239.   
  240.         ftpClient.setFileType(FTP.BINARY_FILE_TYPE);  
  241.   
  242.         FTPStatus result;  
  243.   
  244.         File f = new File(local);  
  245.   
  246.         FTPFile[] files = ftpClient.listFiles(remote);  
  247.   
  248.         if (files.length != 1)  
  249.         {  
  250.             Log.getLogger(this.getClass()).info("远程文件不唯一");  
  251.             return FTPStatus.File_Not_Unique;  
  252.         }  
  253.   
  254.         long lRemoteSize = files[0].getSize();  
  255.   
  256.         if (f.exists())  
  257.         {  
  258.             OutputStream out = new FileOutputStream(f, true);  
  259.             Log.getLogger(this.getClass()).info("本地文件大小为:" + f.length());  
  260.   
  261.             if (f.length() >= lRemoteSize)  
  262.             {  
  263.   
  264.                 Log.getLogger(this.getClass()).info("本地文件大小大于远程文件大小,下载中止");  
  265.                 return FTPStatus.Remote_smaller_local;  
  266.   
  267.             }  
  268.   
  269.             ftpClient.setRestartOffset(f.length());  
  270.   
  271.             boolean status = ftpClient.retrieveFile(remote, out);  
  272.             result=status?FTPStatus.Download_From_Break_Success:FTPStatus.Download_From_Break_Faild;  
  273.             out.close();  
  274.   
  275.         } else  
  276.         {  
  277.             OutputStream out = new FileOutputStream(f);  
  278.             boolean status = ftpClient.retrieveFile(remote, out);  
  279.             result=status?FTPStatus.Download_From_Break_Success:FTPStatus.Download_From_Break_Faild;  
  280.             out.close();  
  281.         }  
  282.   
  283.         return result;  
  284.   
  285.     }  
  286.   
  287.     /** 
  288.      *  
  289.      * 上传文件到FTP服务器,支持断点续传 
  290.      *  
  291.      * @param local 
  292.      *            本地文件名称,绝对路径 
  293.      *  
  294.      * @param remote 
  295.      *            远程文件路径,使用/home/directory1/subdirectory/file.ext 
  296.      *            按照Linux上的路径指定方式,支持多级目录嵌套,支持递归创建不存在的目录结构 
  297.      *  
  298.      * @return 上传结果 
  299.      *  
  300.      * @throws IOException 
  301.      */  
  302.   
  303.     @SuppressWarnings("resource")  
  304.     public FTPStatus upload(String local, String remote) throws IOException  
  305.     {  
  306.         // 设置PassiveMode传输  
  307.         ftpClient.enterLocalPassiveMode();  
  308.   
  309.         // 设置以二进制流的方式传输  
  310.         ftpClient.setFileType(FTP.BINARY_FILE_TYPE);  
  311.   
  312.         FTPStatus result;  
  313.   
  314.         // 对远程目录的处理  
  315.         String remoteFileName = remote;  
  316.   
  317.         if (remote.contains("/"))  
  318.         {  
  319.   
  320.             remoteFileName = remote.substring(remote.lastIndexOf("/") + 1);  
  321.   
  322.             String directory = remote.substring(0, remote.lastIndexOf("/") + 1);  
  323.   
  324.             if (!directory.equalsIgnoreCase("/") && !ftpClient.changeWorkingDirectory(directory))  
  325.             {  
  326.   
  327.                 // 如果远程目录不存在,则递归创建远程服务器目录  
  328.   
  329.                 int start = 0;  
  330.   
  331.                 int end = 0;  
  332.   
  333.                 if (directory.startsWith("/"))  
  334.                 {  
  335.   
  336.                     start = 1;  
  337.   
  338.                 } else  
  339.                 {  
  340.   
  341.                     start = 0;  
  342.   
  343.                 }  
  344.   
  345.                 end = directory.indexOf("/", start);  
  346.   
  347.                 while (true)  
  348.                 {  
  349.   
  350.                     String subDirectory = remote.substring(start, end);  
  351.   
  352.                     if (!ftpClient.changeWorkingDirectory(subDirectory))  
  353.                     {  
  354.   
  355.                         if (ftpClient.makeDirectory(subDirectory))  
  356.                         {  
  357.   
  358.                             ftpClient.changeWorkingDirectory(subDirectory);  
  359.   
  360.                         } else  
  361.                         {  
  362.   
  363.                             Log.getLogger(this.getClass()).info("创建目录失败");  
  364.   
  365.                             return FTPStatus.Create_Directory_Fail;  
  366.   
  367.                         }  
  368.   
  369.                     }  
  370.   
  371.                     start = end + 1;  
  372.   
  373.                     end = directory.indexOf("/", start);  
  374.   
  375.                     // 检查所有目录是否创建完毕  
  376.   
  377.                     if (end <= start)  
  378.                     {  
  379.   
  380.                         break;  
  381.   
  382.                     }  
  383.   
  384.                 }  
  385.   
  386.             }  
  387.   
  388.         }  
  389.   
  390.         // 检查远程是否存在文件  
  391.   
  392.         FTPFile[] files = ftpClient.listFiles(remoteFileName);  
  393.   
  394.         if (files.length == 1)  
  395.         {  
  396.   
  397.             long remoteSize = files[0].getSize();  
  398.   
  399.             File f = new File(local);  
  400.   
  401.             long localSize = f.length();  
  402.   
  403.             if (remoteSize == localSize)  
  404.             {  
  405.   
  406.                 return FTPStatus.File_Exits;  
  407.   
  408.             } else if (remoteSize > localSize)  
  409.             {  
  410.   
  411.                 return FTPStatus.Remote_Bigger_Local;  
  412.   
  413.             }  
  414.   
  415.             // 尝试移动文件内读取指针,实现断点续传  
  416.   
  417.             InputStream is = new FileInputStream(f);  
  418.   
  419.             if (is.skip(remoteSize) == remoteSize)  
  420.             {  
  421.   
  422.                 ftpClient.setRestartOffset(remoteSize);  
  423.   
  424.                 if (ftpClient.storeFile(remote, is))  
  425.                 {  
  426.   
  427.                     return FTPStatus.Upload_From_Break_Success;  
  428.   
  429.                 }  
  430.   
  431.             }  
  432.   
  433.             // 如果断点续传没有成功,则删除服务器上文件,重新上传  
  434.   
  435.             if (!ftpClient.deleteFile(remoteFileName))  
  436.             {  
  437.   
  438.                 return FTPStatus.Delete_Remote_Faild;  
  439.   
  440.             }  
  441.   
  442.             is = new FileInputStream(f);  
  443.   
  444.             if (ftpClient.storeFile(remote, is))  
  445.             {  
  446.   
  447.                 result = FTPStatus.Upload_New_File_Success;  
  448.   
  449.             } else  
  450.             {  
  451.   
  452.                 result = FTPStatus.Upload_New_File_Failed;  
  453.   
  454.             }  
  455.   
  456.             is.close();  
  457.   
  458.         } else  
  459.         {  
  460.   
  461.             InputStream is = new FileInputStream(local);  
  462.   
  463.             if (ftpClient.storeFile(remoteFileName, is))  
  464.             {  
  465.   
  466.                 result = FTPStatus.Upload_New_File_Success;  
  467.   
  468.             } else  
  469.             {  
  470.   
  471.                 result = FTPStatus.Upload_New_File_Failed;  
  472.   
  473.             }  
  474.   
  475.             is.close();  
  476.         }  
  477.   
  478.         return result;  
  479.   
  480.     }  
  481.   
  482.     /** 
  483.      *  
  484.      * 断开与远程服务器的连接 
  485.      *  
  486.      * @throws IOException 
  487.      */  
  488.   
  489.     public void disconnect() throws IOException  
  490.     {  
  491.   
  492.         if (ftpClient.isConnected())  
  493.         {  
  494.             ftpClient.disconnect();  
  495.         }  
  496.   
  497.     }  
  498.   
  499.   
  500.     @Override  
  501.     public void run()  
  502.     {  
  503.         boolean status=false;  
  504.         // 建立FTP连接  
  505.         try  
  506.         {  
  507.             ftpClient.connect(userInfo.getIp(), userInfo.getPort());  
  508.   
  509.             if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode()))  
  510.             {  
  511.   
  512.                 if (ftpClient.login(userInfo.getUsername(), userInfo.getPassword()))  
  513.                 {  
  514.                     status=true;  
  515.                 }  
  516.             }else{  
  517.                 try  
  518.                 {  
  519.                     disconnect();  
  520.                 } catch (IOException e)  
  521.                 {  
  522.                       
  523.                     e.printStackTrace();  
  524.                 }  
  525.             }  
  526.         } catch (SocketException e1)  
  527.         {  
  528.               
  529.             e1.printStackTrace();  
  530.         } catch (IOException e1)  
  531.         {  
  532.             e1.printStackTrace();  
  533.         }  
  534.         // FTP连接成功后执行相应的操作  
  535.         if(status){  
  536.             FTPStatus result=null;  
  537.             if(this.ftpType==FTPType.UPLOAD)  
  538.             {  
  539.                 try  
  540.                 {  
  541.                     result=this.upload(userInfo.getLocal(), userInfo.getRemote());// 上传文件  
  542.                 } catch (IOException e)  
  543.                 {  
  544.                     Log.getLogger(ThreadFTPUtils.class).info("FTP上传文件异常:" + e.getMessage());  
  545.                 }  
  546.             }else if(this.ftpType==FTPType.DOWNLOAD)  
  547.             {  
  548.                 try  
  549.                 {  
  550.                     result=this.download(userInfo.getRemote(), userInfo.getLocal());// 下载文件  
  551.                 } catch (IOException e)  
  552.                 {  
  553.                     Log.getLogger(ThreadFTPUtils.class).info("FTP下载文件异常:" + e.getMessage());  
  554.                 }  
  555.             }else if(this.ftpType==FTPType.RENAME)  
  556.             {  
  557.                 try  
  558.                 {  
  559.                     result=this.rename(userInfo.getLocal(), userInfo.getRemote());// 修改名称  
  560.                 } catch (IOException e)  
  561.                 {  
  562.                     Log.getLogger(ThreadFTPUtils.class).info("FTP修改文件名称异常:" + e.getMessage());  
  563.                 }             
  564.             }else if(this.ftpType==FTPType.DELETE)  
  565.             {  
  566.                 try  
  567.                 {  
  568.                     result=this.delete(userInfo.getRemote());                    // 删除文件  
  569.                 } catch (IOException e)  
  570.                 {  
  571.                     Log.getLogger(ThreadFTPUtils.class).info("FTP删除文件异常:" + e.getMessage());  
  572.                 }  
  573.             }  
  574.             try  
  575.             {  
  576.                 disconnect();  
  577.             } catch (IOException e)  
  578.             {  
  579.                   
  580.                 Log.getLogger(ThreadFTPUtils.class).info("FTP连接释放异常:" + e.getMessage());  
  581.             }  
  582.             Log.getLogger(this.getClass()).info("FTP操作状态码:"+result);  
  583.         }  
  584.           
  585.     }  
  586.       
  587.     public static void main(String[] args)  
  588.     {  
  589.         ThreadFTPUtils myFtp = new ThreadFTPUtils("192.168.1.200", 21, "duser", "HTPDuserXP32","C:\\Users\\Administrator\\Desktop\\swing.drawer.jar","/jars/boonya.jar",FTPType.UPLOAD);  
  590.         Thread thread=new Thread(myFtp);  
  591.         thread.start();  
  592.   
  593.     }  
  594.   
  595. }  
  596.   
  597. class UserInfo{  
  598.       
  599.     private String ip;      //FTP服务器的IP地址  
  600.       
  601.     private int port;       //FTP服务器端口  
  602.       
  603.     private String username;//登录用户名  
  604.       
  605.     private String password;//登录密码  
  606.       
  607.     private String local;   //本地文件或文件名  
  608.       
  609.     private String remote;  //远程文件或路径  
  610.       
  611.     public String getIp()  
  612.     {  
  613.         return ip;  
  614.     }  
  615.   
  616.     public void setIp(String ip)  
  617.     {  
  618.         this.ip = ip;  
  619.     }  
  620.   
  621.     public int getPort()  
  622.     {  
  623.         return port;  
  624.     }  
  625.   
  626.     public void setPort(int port)  
  627.     {  
  628.         this.port = port;  
  629.     }  
  630.   
  631.     public String getUsername()  
  632.     {  
  633.         return username;  
  634.     }  
  635.   
  636.     public void setUsername(String username)  
  637.     {  
  638.         this.username = username;  
  639.     }  
  640.   
  641.     public String getPassword()  
  642.     {  
  643.         return password;  
  644.     }  
  645.   
  646.     public void setPassword(String password)  
  647.     {  
  648.         this.password = password;  
  649.     }  
  650.   
  651.     public String getLocal()  
  652.     {  
  653.         return local;  
  654.     }  
  655.   
  656.     public void setLocal(String local)  
  657.     {  
  658.         this.local = local;  
  659.     }  
  660.   
  661.     public String getRemote()  
  662.     {  
  663.         return remote;  
  664.     }  
  665.   
  666.     public void setRemote(String remote)  
  667.     {  
  668.         this.remote = remote;  
  669.     }  
  670.   
  671.     public UserInfo()  
  672.     {  
  673.           
  674.     }  
  675.   
  676.     public UserInfo(String ip, int port, String username, String password, String local, String remote)  
  677.     {  
  678.         this.ip = ip;  
  679.         this.port = port;  
  680.         this.username = username;  
  681.         this.password = password;  
  682.         this.local = local;  
  683.         this.remote = remote;  
  684.     }  
  685.       
  686. }  


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多