分享

基于Apache FTP实现的文件上传下载工具

 心不留意外尘 2016-07-17

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

2014

基于Apache FTP实现的文件上传下载工具 ,上传文件时需要考虑以下问题:

(1)、 FTP服务器是否存在改目录,如果不存在目录则需要创建目录。

(2)、判断上传文件是否已经存在,如果存在是需要删除覆盖上传还是续传。

以下示例代码(注:未实现续传功能)。

  1. package com.scengine.wtms.utils.ftp;  
  2.   
  3. import java.io.ByteArrayOutputStream;  
  4. import java.io.File;  
  5. import java.io.FileInputStream;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8. import java.io.InputStream;  
  9. import java.io.OutputStream;  
  10. import java.io.PrintWriter;  
  11. import java.net.SocketException;  
  12. import java.net.URLEncoder;  
  13. import javax.servlet.http.HttpServletResponse;  
  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.FTPClientConfig;  
  18. import org.apache.commons.net.ftp.FTPFile;  
  19. import org.apache.commons.net.ftp.FTPReply;  
  20.   
  21. import com.scengine.wtms.utils.Log;  
  22.   
  23. public class OLDFashionedFTP  
  24. {  
  25.     private FTPClient ftp;  
  26.   
  27.     /** 
  28.      * 对象构造 设置将过程中使用到的命令输出到控制台 
  29.      */  
  30.     public OLDFashionedFTP()  
  31.     {  
  32.         ftp = new FTPClient();  
  33.         this.ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));  
  34.     }  
  35.   
  36.     /** 
  37.      * 用户FTP账号登录 
  38.      *  
  39.      * @param url 
  40.      *            FTP地址 
  41.      * @param port 
  42.      *            FTP端口 
  43.      * @param username 
  44.      *            用户名 
  45.      * @param password 
  46.      *            密 码 
  47.      * @return true/false 成功/失败 
  48.      * @throws SocketException 
  49.      * @throws IOException 
  50.      */  
  51.     private boolean login(String url, int port, String username, String password) throws SocketException, IOException  
  52.     {  
  53.         int reply;  
  54.         // 1. 连接FTP服务器  
  55.         // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器  
  56.         ftp.connect(url, port);  
  57.   
  58.         // 2. 设置编码  
  59.         // 下面三行代码必须要,而且不能改变编码格式,否则不能正确下载中文文件  
  60.         ftp.setControlEncoding("UTF-8");  
  61.         FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);  
  62.         conf.setServerLanguageCode("zh");  
  63.   
  64.         // 3. 登录ftp  
  65.         ftp.login(username, password);  
  66.   
  67.         // 看返回的值是不是230,如果是,表示登陆成功  
  68.         reply = ftp.getReplyCode();  
  69.   
  70.         // 以2开头的返回值就会为真  
  71.         if (!FTPReply.isPositiveCompletion(reply))  
  72.         {  
  73.             ftp.disconnect();  
  74.             Log.getLogger(this.getClass()).info(">>>>>>>>>>>>>>>>连接服务器失败!");  
  75.             return false;  
  76.         }  
  77.         Log.getLogger(this.getClass()).info(">>>>>>>>>>>>>>>>>登陆服务器成功!");  
  78.         return true;  
  79.     }  
  80.   
  81.     /** 
  82.      * 释放FTP 
  83.      */  
  84.     public void disconnect()  
  85.     {  
  86.         if (ftp.isAvailable())  
  87.         {  
  88.             try  
  89.             {  
  90.                 ftp.logout(); // 退出FTP  
  91.             } catch (IOException e)  
  92.             {  
  93.                 Log.getLogger(this.getClass()).error("FTP登录退出异常:" + e.getMessage());  
  94.             }  
  95.         }  
  96.         if (ftp.isConnected())  
  97.         {  
  98.             try  
  99.             {  
  100.                 // 断开连接  
  101.                 ftp.disconnect();  
  102.             } catch (IOException e)  
  103.             {  
  104.                 Log.getLogger(this.getClass()).error("FTP断开连接异常:" + e.getMessage());  
  105.             }  
  106.         }  
  107.     }  
  108.   
  109.     /** 
  110.      * FTP文件上传 
  111.      *  
  112.      * @param url 
  113.      *            FTP地址 
  114.      * @param port 
  115.      *            FTP端口 
  116.      * @param username 
  117.      *            FTP用户名 
  118.      * @param password 
  119.      *            FTP密码 
  120.      * @param localAdr 
  121.      *            上传文件名 
  122.      * @param remoteAdr 
  123.      *            指定的FTP目录 
  124.      * @return 
  125.      * @throws IOException 
  126.      */  
  127.     public boolean uploadFile(String url, int port, String username, String password, String localAdr, String remoteAdr) throws IOException  
  128.     {  
  129.   
  130.         // 初始表示上传失败  
  131.         boolean success = false;  
  132.         /******验证用户登录信息*****/  
  133.         try  
  134.         {  
  135.             success = login(url, port, username, password);  
  136.   
  137.             Log.getLogger(this.getClass()).info("FTP用户登录:" + (success ? "成功!" : "失败!"));  
  138.             if (!success)  
  139.             {  
  140.                 return success;  
  141.             }  
  142.         } catch (IOException e)  
  143.         {  
  144.             Log.getLogger(this.getClass()).error("上传文件异常:" + e.getMessage());  
  145.             return success;  
  146.         }  
  147.         // 设置PassiveMode传输  
  148.         ftp.enterLocalPassiveMode();  
  149.   
  150.         // 设置FTP文件类型为二进制,如果缺省该句 传输txt正常 但图片和其他格式的文件传输出现乱码  
  151.         ftp.setFileType(FTP.BINARY_FILE_TYPE);  
  152.   
  153.         /*****对远程目录的处理******/  
  154.         String remoteFileName = remoteAdr;  
  155.   
  156.         if (remoteAdr.contains("/"))  
  157.         {  
  158.             remoteFileName = remoteAdr.substring(remoteAdr.lastIndexOf("/") + 1);  
  159.             String directory = remoteAdr.substring(0, remoteAdr.lastIndexOf("/") + 1);  
  160.   
  161.             if (!directory.equalsIgnoreCase("/") && !ftp.changeWorkingDirectory(directory))  
  162.             {  
  163.   
  164.                 // 如果远程目录不存在,则递归创建远程服务器目录  
  165.                 int start = 0, end = 0;  
  166.   
  167.                 if (directory.startsWith("/"))  
  168.                 {  
  169.                     start = 1;  
  170.                 } else  
  171.                 {  
  172.                     start = 0;  
  173.                 }  
  174.   
  175.                 end = directory.indexOf("/", start);  
  176.   
  177.                 while (true)  
  178.                 {  
  179.   
  180.                     String subDirectory = remoteAdr.substring(start, end);  
  181.   
  182.                     if (!ftp.changeWorkingDirectory(subDirectory))  
  183.                     {  
  184.   
  185.                         if (ftp.makeDirectory(subDirectory))  
  186.                         {  
  187.   
  188.                             ftp.changeWorkingDirectory(subDirectory);  
  189.   
  190.                         } else  
  191.                         {  
  192.                             Log.getLogger(this.getClass()).info("创建目录失败");  
  193.                             return false;  
  194.                         }  
  195.                     }  
  196.                     start = end + 1;  
  197.                     end = directory.indexOf("/", start);  
  198.                     // 检查所有目录是否创建完毕  
  199.                     if (end <= start)  
  200.                     {  
  201.                         break;  
  202.                     }  
  203.                 }  
  204.             }  
  205.         }  
  206.   
  207.         /*****执行文件上传******/  
  208.         InputStream input = null;  
  209.         try  
  210.         {  
  211.             File f = new File(localAdr);  
  212.             // 得到目录的相应文件列表  
  213.             FTPFile[] fs = ftp.listFiles(remoteFileName);  
  214.   
  215.             Log.getLogger(this.getClass()).info("上传文件个数:" + fs.length + "  ,文件名称:" + localAdr);  
  216.   
  217.             input = new FileInputStream(f);  
  218.             // 保存文件remoteFileName  
  219.             success = ftp.storeFile(remoteFileName, input);  
  220.               
  221.         } catch (IOException e)  
  222.         {  
  223.             if (input != null)  input.close();  
  224.             Log.getLogger(this.getClass()).info("上传文件失败:" + e.getMessage());  
  225.         } finally  
  226.         {  
  227.             if (input != null)  input.close();  
  228.             this.disconnect();  
  229.             Log.getLogger(this.getClass()).info("保存标识>>>" + success + "文件名称:" + localAdr + (success ? "上传成功!" : "上传失败!"));  
  230.         }  
  231.         return success;  
  232.     }  
  233.   
  234.     /** 
  235.      * 删除FTP文件和目录 
  236.      *  
  237.      * @param url 
  238.      *            FTP地址 
  239.      * @param port 
  240.      *            FTP端口 
  241.      * @param username 
  242.      *            用户名 
  243.      * @param password 
  244.      *            密 码 
  245.      * @param remoteAdr 
  246.      *            文件路径 
  247.      * @param localAdr 
  248.      *            文件名称 
  249.      * @return true/false 成功/失败 
  250.      */  
  251.     public boolean deleteDirectory(String url, int port, String username, String password, String remoteAdr)  
  252.     {  
  253.         boolean success = false;  
  254.   
  255.         try  
  256.         {  
  257.             success = login(url, port, username, password);  
  258.             Log.getLogger(this.getClass()).info("FTP用户登录:" + (success ? "成功!" : "失败!"));  
  259.             if (!success)  
  260.             {  
  261.                 return success;  
  262.             }  
  263.   
  264.             //String remoteAdr_ = new String(remoteAdr.getBytes("UTF-8"), "ISO-8859-1");  
  265.   
  266.             // 转到指定上传目录  
  267.             ftp.changeWorkingDirectory(remoteAdr);  
  268.   
  269.             FTPFile[] fs = ftp.listFiles(); // 得到目录的相应文件列表  
  270.             if(fs.length>0)  
  271.             {  
  272.                 success = ftp.removeDirectory(remoteAdr);  
  273.   
  274.             }  
  275.   
  276.         } catch (IOException e)  
  277.         {  
  278.             Log.getLogger(this.getClass()).error(e.getMessage());  
  279.         } finally  
  280.         {  
  281.             this.disconnect();  
  282.         }  
  283.   
  284.         return success;  
  285.     }  
  286.   
  287.     /** 
  288.      * 删除FTP文件 
  289.      *  
  290.      * @param url 
  291.      *            FTP地址 
  292.      * @param port 
  293.      *            FTP端口 
  294.      * @param username 
  295.      *            用户名 
  296.      * @param password 
  297.      *            密 码 
  298.      * @param remoteAdr 
  299.      *            文件路径 
  300.      * @return true/false 成功/失败 
  301.      */  
  302.     public boolean deleteFile(String url, int port, String username, String password, String remoteAdr)  
  303.     {  
  304.         boolean success = false;  
  305.   
  306.         try  
  307.         {  
  308.             success = login(url, port, username, password);  
  309.             Log.getLogger(this.getClass()).info("FTP用户登录:" + (success ? "成功!" : "失败!"));  
  310.             if (!success)  
  311.             {  
  312.                 return success;  
  313.             }  
  314.   
  315.             //String remoteAdr_ = new String(remoteAdr.getBytes("UTF-8"), "ISO-8859-1");  
  316.   
  317.             // 得到目录的相应文件列表  
  318.             FTPFile[] fs = ftp.listFiles(remoteAdr);;   
  319.               
  320.             if(fs.length>0)  
  321.             {  
  322.                 // remoteAdr_->remoteAdr  
  323.                 success =ftp.deleteFile(remoteAdr);  
  324.             }  
  325.         } catch (IOException e)  
  326.         {  
  327.             Log.getLogger(this.getClass()).error(e.getMessage());  
  328.         } finally  
  329.         {  
  330.             this.disconnect();  
  331.         }  
  332.         return success;  
  333.     }  
  334.   
  335.     /** 
  336.      * 下载FTP文件 
  337.      *  
  338.      * @param url 
  339.      *            FPT地址 
  340.      * @param port 
  341.      *            FTP端口 
  342.      * @param username 
  343.      *            用户名 
  344.      * @param password 
  345.      *            密 码 
  346.      * @param remoteremoteAdr 
  347.      *            远程路径 
  348.      * @param localAdr 
  349.      *            文件名称 
  350.      * @param outputStream文件输出流 
  351.      * @param response 
  352.      *            Http响应 
  353.      * @return true/false 成功/失败 
  354.      */  
  355.     public boolean downFile(String url, int port, String username, String password, String remoteremoteAdr, String localAdr, HttpServletResponse response)  
  356.     {  
  357.         boolean success = false;  
  358.         try  
  359.         {  
  360.             success = login(url, port, username, password);  
  361.             Log.getLogger(this.getClass()).info("FTP用户登录:" + (success ? "成功!" : "失败!"));  
  362.             if (!success)  
  363.             {  
  364.                 return success;  
  365.             }  
  366.             // 转移到FTP服务器目录  
  367.             ftp.changeWorkingDirectory(remoteremoteAdr);  
  368.             // 得到目录的相应文件列表  
  369.             FTPFile[] fs = ftp.listFiles();  
  370.               
  371.             for (FTPFile ftpFile : fs)  
  372.             {  
  373.                 if (ftpFile.getName().equals(localAdr))  
  374.                 {  
  375.                     // 这个就就是弹出下载对话框的关键代码  
  376.                     response.setHeader("Content-disposition", "attachment;localAdr=" + URLEncoder.encode(localAdr, "UTF-8"));  
  377.                     // 将文件保存到输出流outputStream中  
  378.                     File f=new File(localAdr);  
  379.                     OutputStream os=new FileOutputStream(f);  
  380.                     ftp.retrieveFile(new String(ftpFile.getName().getBytes("UTF-8"), "ISO-8859-1"), os);  
  381.                     os.flush();  
  382.                     os.close();  
  383.                 }  
  384.             }  
  385.             success = true;  
  386.         } catch (IOException e)  
  387.         {  
  388.             e.printStackTrace();  
  389.         } finally  
  390.         {  
  391.             this.disconnect();  
  392.         }  
  393.         return success;  
  394.     }  
  395.   
  396.     /** 
  397.      * 读取FTP文件内容 
  398.      *  
  399.      * @param url 
  400.      *            FPT地址 
  401.      * @param port 
  402.      *            FTP端口 
  403.      * @param username 
  404.      *            用户名 
  405.      * @param password 
  406.      *            密 码 
  407.      * @param remoteremoteAdr 
  408.      *            远程路径 
  409.      * @param localAdr 
  410.      *            文件名称 
  411.      * @return String 文件内容 
  412.      */  
  413.     public String readFileContent(String url, int port, String username, String password, String remoteremoteAdr, String localAdr)  
  414.     {  
  415.         String content = null;  
  416.         try  
  417.         {  
  418.             boolean success = login(url, port, username, password);  
  419.             Log.getLogger(this.getClass()).info("FTP用户登录:" + (success ? "成功!" : "失败!"));  
  420.             if (success)  
  421.             {  
  422.                 // 转移到FTP服务器目录  
  423.                 ftp.changeWorkingDirectory(remoteremoteAdr);   
  424.                   
  425.                 // 得到目录的相应文件列表  
  426.                 FTPFile[] fs = ftp.listFiles();  
  427.                   
  428.                 for (FTPFile ftpFile : fs)  
  429.                 {  
  430.                     if (ftpFile.getName().equals(localAdr))  
  431.                     {  
  432.                         // 这个就就是弹出下载对话框的关键代码  
  433.                         // 将文件保存到输出流outputStream中  
  434.                         File f=new File(localAdr);  
  435.                         ftp.retrieveFile(new String(ftpFile.getName().getBytes("UTF-8"), "ISO-8859-1"), new FileOutputStream(f));  
  436.                         ByteArrayOutputStream bos = new ByteArrayOutputStream();  
  437.                         ftp.retrieveFile(ftpFile.getName(), bos);  
  438.                         bos.flush();  
  439.                         bos.close();  
  440.   
  441.                         content = new String(bos.toByteArray(), "UTF-8");  
  442.                     }  
  443.                 }  
  444.             }  
  445.         } catch (IOException e)  
  446.         {  
  447.             Log.getLogger(FTPUtils.class).error(e.getMessage());  
  448.         } finally  
  449.         {  
  450.             this.disconnect();   
  451.         }  
  452.         return content;  
  453.     }  
  454.   
  455.     /** 
  456.      * 判断是否重名的方法 
  457.      *  
  458.      * @param localAdr 
  459.      *            文件名称 
  460.      * @param fs 
  461.      *            文件列表数组 
  462.      * @return 
  463.      */  
  464.     public static boolean isDirExist(String localAdr, FTPFile[] fs)  
  465.     {  
  466.         for (FTPFile ftpFile : fs)  
  467.         {  
  468.             if (ftpFile.getName().equals(localAdr))  
  469.             {  
  470.                 return true;  
  471.             }  
  472.         }  
  473.         return false;  
  474.     }  
  475.   
  476.     /** 
  477.      * 根据重名判断的结果 生成新的文件的名称 更改的重名为 原有名字+[n], n表示数字 
  478.      *  
  479.      * @param localAdr 
  480.      *            文件名称 
  481.      * @param fs 
  482.      *            FTP文件列表 
  483.      * @return 
  484.      */  
  485.     public static String rename(String localAdr, FTPFile[] fs)  
  486.     {  
  487.         int n = 0;  
  488.         // 创建一个可变的字符串对象 即StringBuffer对象,把localAdr值付给该对象  
  489.         StringBuffer localAdr_ = new StringBuffer("");  
  490.         localAdr_ = localAdr_.append(localAdr);  
  491.   
  492.         // 重名时改名,遍历存在同名的文件  
  493.         while (isDirExist(localAdr_.toString(), fs))  
  494.         {  
  495.             n++;  
  496.             String a = "[" + n + "]";  
  497.             // 最后一出现小数点的位置  
  498.             int b = localAdr_.lastIndexOf(".");  
  499.             // 最后一次"["出现的位置  
  500.             int c = localAdr_.lastIndexOf("[");  
  501.             if (c < 0)  
  502.             {  
  503.                 c = b;  
  504.             }  
  505.   
  506.             // 文件的名字  
  507.             StringBuffer name = new StringBuffer(localAdr_.substring(0, c));  
  508.             // 后缀的名称  
  509.             StringBuffer suffix = new StringBuffer(localAdr_.substring(b + 1));  
  510.             localAdr_ = name.append(a).append(".").append(suffix);  
  511.         }  
  512.         return localAdr_.toString();  
  513.     }  
  514.   
  515.     public static void main(String[] args)  
  516.     {  
  517.         OLDFashionedFTP ftp = new OLDFashionedFTP();  
  518.         try  
  519.         {  
  520.             ftp.uploadFile("192.168.1.200", 21, "duser", "HTPDuserXP32", "C:\\Users\\Administrator\\Desktop\\backgroud_change.html", "/htmls/backgroud_change.html");  
  521.         } catch (IOException e)  
  522.         {  
  523.             Log.getLogger(OLDFashionedFTP.class).error(e.getMessage());  
  524.         }  
  525.     }  
  526.   
  527. }  

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

    0条评论

    发表

    请遵守用户 评论公约