applet实现大文件ftp上传(一)

由于要用APPLET实现大文件FTP上传下载,从网上搜索了几下,找到很多资料,最后决定采用基于 org.apache.commons.net.ftp包实现FTP上传下载,Net包中的类既提供对协议的底层访问也有高层的抽象。在大多数情况下,抽 象是足够的,它可以使你不必编写解析各种协议的底层套接字的代码。使用抽象不会损失任何功能。

    借此感叹,org.apache.commons开源包真是森罗万象,应有尽有。反观国内打着开源旗号的软件也不少,但没几个能在当前软林扬名立万的,借山本赵一句经典台词:悲哀 悲哀 真是悲哀。

    开发环境:winxp+eclipse3.2.2+struts2.0+jse5.0

    最早采用以下代码:

package yp;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.io.PrintWriter;

import java.io.RandomAccessFile;

import java.util.ArrayList;

import java.util.List;

import org.apache.commons.net.PrintCommandListener;

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 ContinueFTP{   

   private File file=null;

   //是否完整保留原文件名

   private boolean isSaveFileName = true;

   //枚举上传状态

   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,    //远程文件不存在 

          Local_Bigger_Remote,    //本地文件大于远程文件 

          Download_From_Break_Success,    //断点下载文件成功 

          Download_From_Break_Failed,     //断点下载文件失败 

          Download_New_Success,           //全新下载文件成功 

          Download_New_Failed;            //全新下载文件失败 

    }

   

    public void init(){

    

    }

   

    public FTPClient ftpClient = new FTPClient(); 

        

     public ContinueFTP(){ 

           //设置将过程中使用到的命令输出到控制台 

           this.ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out))); 

     } 

      

   

    public String getRemoteFileName(String localFileName){

     String fileName ="";

     //分隔符

     String sepaRator="\";

        if (localFileName.indexOf(sepaRator)<0)

         sepaRator="/";

        //最后分隔符位置

        int idx = localFileName.lastIndexOf(sepaRator)+1;

        fileName = localFileName.substring(idx);

        return fileName;

    }    

     

      

       public boolean isFileExist(String remoteFileName) throws IOException{

        boolean isFileExist = false;          

           //检查远程是否存在文件 

           FTPFile[] files = ftpClient.listFiles(new String(remoteFileName.getBytes("GBK"),"iso-8859-1")); 

           if(files!=null && files.length >= 1){ 

              isFileExist = true;

        }

        return isFileExist;

       }

      

      

        

       public boolean connect(String hostname,int port,String username,String password) throws Exception{ 

        boolean bl = false;

        try{

         ftpClient.connect(hostname, port); 

        }catch(Exception e){

          //可具体报错到主机和端口号

      throw new BaseException("FTPConnError01",new String[]{"connect",e.getMessage()});

        }

        try{

         //ftpClient.setControlEncoding("GBK");

            if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){ 

                if(ftpClient.login(username, password)){ 

                 bl = true; 

                } 

            }

        }catch(Exception e){

          //可具体报错到用户和密码

      throw new BaseException("FTPConnError02",new String[]{"connect",e.getMessage()});

        }

           return bl; 

       } 

        

        

       public DownloadStatus download(String remote,String local) throws Exception{ 

           //设置被动模式 

           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){ 

            throw new BaseException("CellDataInputService",new String[]{"download","远程文件"+remote+"不存在"});

           } 

            

           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; 

       }        

       public UploadStatus upload(File localFile,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!=null && files.length == 1){ 

               long remoteSize = files[0].getSize(); 

               //File f = new File(local); 

               long localSize = localFile.length(); 

               if(remoteSize==localSize){ 

                   return UploadStatus.File_Exits; 

               }else if(remoteSize > localSize){ 

                   return UploadStatus.Remote_Bigger_Local; 

               } 

                

               //尝试移动文件内读取指针,实现断点续传 

               result = uploadFile(remoteFileName, localFile, ftpClient, remoteSize); 

                

               //如果断点续传没有成功,则删除服务器上文件,重新上传 

               if(result == UploadStatus.Upload_From_Break_Failed){ 

                   if(!ftpClient.deleteFile(remoteFileName)){ 

                       return UploadStatus.Delete_Remote_Faild; 

                   } 

                   result = uploadFile(remoteFileName, localFile, ftpClient, 0); 

               } 

           }else { 

               result = uploadFile(remoteFileName, localFile, ftpClient, 0); 

           } 

           return result; 

       } 

        

       public void disconnect() throws IOException{ 

           if(this.ftpClient.isConnected()){ 

            this.ftpClient.disconnect(); 

           } 

       } 

        

      

       public String CreateDirecroty(String remoteDir)throws IOException{

        String fillDir = "";

              UploadStatus st = CreateDirecroty(remoteDir,this.ftpClient);

              if (st == UploadStatus.Create_Directory_Success)

          fillDir = remoteDir;

        else

        fillDir = "";

             

        return fillDir;

       }

      

        

       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; 

       } 

        

        

       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; 

                  //TODO 汇报上传状态 

               if(localreadbytes / step != process){ 

                   process = localreadbytes / step; 

                   System.out.println("上传进度:" + process); 

               } 

           } 

           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 List<String> getRemoteFileList(String remoteDir){

         List<String> list = new ArrayList<String>();

              FTPFile[] files;

     try {

      files = ftpClient.listFiles(remoteDir);

               for (int i = 0; i < files.length; i++) {

                list.add(files[i].getName());

               }

     } catch (IOException e) {

      // TODO Auto-generated catch block

      e.printStackTrace();

     }

              return list;

        }

      

      

       public boolean deleteFile(String fillFileName) throws Exception {

        boolean bl = false;

        this.ftpClient.deleteFile(fillFileName);

           int status = this.ftpClient.getReplyCode();

           if(status == 250){

            bl = true;

            System.out.println("成功删除FTP服务器中文件:" + fillFileName);           

           }

           return bl;

       }

 

         public boolean deleteDir(String remoteDir)throws Exception {

        boolean isDel = false;

        this.ftpClient.removeDirectory(remoteDir);

           int status = this.ftpClient.getReplyCode();

           if(status == 250){

            isDel = true;

            System.out.println("成功删除FTP服务器中目录:" + remoteDir);           

           }

        return isDel;

       }

        

       public static void main(String[] args) throws Exception {

        ContinueFTP myFtp = new ContinueFTP(); 

        try { 

            long l1 = System.currentTimeMillis();

            System.out.println("begin:"+ l1);

               if (myFtp.connect("10.68.7.182", 21, "a", "a")) {

                String mkDir = myFtp.CreateDirecroty("TTT/ccc/");

                if (mkDir != null && !mkDir.trim().equals(""))

                 System.out.println("mkDir success:"+mkDir);

                //myFtp.download( "/XA01B03H05/5.mp3",file,"0");

                //myFtp.upload("/XA01B03H05/5.mp3", "/云台山.mpg");

                //myFtp.delete_file("/tmp.txt");

                //String str = new String("电视剧");

                //myFtp.ftpClient.removeDirectory("/kkk/jk/");

                //myFtp.ftpClient.makeDirectory(new String(str.getBytes("GBK"),"iso-8859-1"));

                myFtp.disconnect();

             long l2 = System.currentTimeMillis();

             System.out.println("end:"+ l2);

                System.out.println("remaining:"+(l2-l1));

               }

           } catch (IOException e) { 

               System.out.println("连接FTP出错:"+e.getMessage()); 

           }

         

       }

   public File getFile() {

    return file;

   }

   public void setFile(File file) {

    this.file = file;

   }

   public boolean isSaveFileName() {

    return isSaveFileName;

   }

   public void setSaveFileName(boolean isSaveFileName) {

    this.isSaveFileName = isSaveFileName;

   }

  

  

}

 

    通过main函数测试效果也不错,还显示上传或下载进度,再写一个对应action及jsp实现ftp上传下载,不过我吃过一次大亏,本来web服务器是本机,我原来做的上传下载都没有问题,但web服务器不在本机,就报说找不到文件!

    后来终于想明白了,系统还是web服务器上路径找文件,当然找不到。

    难道通过浏览器访问本地资源就真的无解了吗?

    当然不是,也在找了很多解决方案,各有所长,又各有短处.

1.使用表单直接提交

  这个方案肯定是被弊掉的,人一多就可能拖跨服务器.

2.使用FLASH进行文件上传

  这个方案也尝试过,不过据说AS3只支持100M左右的文件上传,大文件无法上传,不知道是不是这样?如果是这样的话,那么这个方案也将行不通了.使用FLASH进行文件上传相对而言开发不会太困难.

3.使用APPLET进行文件上传

  使用APPLET开发文件上传控件,这个对于使用JAVA来进行开发的非常方便,因为我们项目就是使用JAVA的,不过APPLET有安全策略的问题,无 法读取客户端的问题.如果要,那么用户必须修改其java.policy文件,这对于用户来讲简直是不可能的.如果使用程序下载动态修改也会比较麻烦.其 实还有一个破解之法,就是采用数字证书。

  缺点:1)、客户端必须安装JRE;2)、想办法突破APPLET有安全策略的问题

  优点:java编写,支持多浏览器

4.使用ACTIVEX进行文件上传

  这是我目前认为比较可行的方式,而且网上也有很多类似这样的控件,但是都不是免费的,所以只能自己想办法解决了.使用ACTIVEX开发,可以使用C++、DELPHI等来进行开发

  缺点:1>客户端推荐IE;2>IE安全设置中启用activex控件

  优点:ACTIVEX开发速度快、界面友好

  以下方案先采用第三种方案---Java applet,当年让Java 大火了一把的号称与微软的ActiveX 相提并论的技术当然,现在Java 出了JavaFX,是不是Applet 的替代品呢?你猜,猜不着呀?你再猜^_^

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/248989.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微软最爽命令行工具发布!

最近微软发布了命令行工具Windows Terminal&#xff0c;简直要让我们爽翻天 长期以来&#xff0c;Linux和Mac下的命令行工具自成一派&#xff0c;Windows却是另一套命令系统。这就比较恶心了&#xff0c;这也是很多开发者不选择Windows系统的原因。 但是现在完全不一样了&#…

定时任务 Cron表达式

Cron表达式由6~7项组成&#xff0c;中间用空格分开。从左到右依次是&#xff1a; 秒、分、时、日、月、周几、年&#xff08;可省略&#xff09; Cron表达式的值可以是数字&#xff0c;也可以是以下符号&#xff1a; "*"&#xff1a;所有值都匹配 "?"&…

vue项目中 axios请求拦截器与取消pending请求功能 - 年少、 - 博客园

在开发vue项目中&#xff0c;请求是不可缺少的&#xff0c;在发送请求时常常需要统一处理一些请求头参数等设置与响应事件&#xff0c;这时利用请求拦截器再好不过。 这里以axios请求为例 实现了设置统一请求头添加token, 其中token在登录时被存入了localStorage中。 同时拦…

gitbook 入门教程之解决windows热加载失败问题

破镜如何贴花黄 gitbook 在 Windows 系统无法热加载,总是报错! gitbook 是一款文档编写利器,可以方便地 markdown 输出成美观优雅的 html ,gitbook serve 启动服务器后,原来相貌平平的 markdown 丑小鸭摇身一变就成了倾国倾城的 html 绝色佳人. 如果源文件发生更改,Windows 却无…

理解DOM事件流的三个阶段 - Lxxyx的开发笔记 - SegmentFault 思否

本文主要解决两个问题&#xff1a; 什么是事件流 DOM事件流的三个阶段 起因 在学习前端的大半年来&#xff0c;对DOM事件了解甚少。一般也只是用用onclick来绑定个点击事件。在寒假深入学习JavaScript时&#xff0c;愈发觉得自己对DOM事件了解不够&#xff0c;遂打开我的《J…

支付宝APP支付 统一下单 php服务端 tp5

/*支付宝第三方支付 * *生成APP支付订单信息 * param number  uid 用户id * param string   token 用户token * param number  oid 订单id * param string   title 标题 * param string    body …

python第十九天(random、json、pickle、hashlib、hmac、shutil、shevle模块)

今日内容&#xff1a; 1. random 模块 2. json模块 3. pickle 模块 4.hashlib 模块 5. hmac 模块 6. shutil 模块 7. shelve 模块 1. random 模块&#xff1a; random 模块 获取随机值import randomfor i in range(10): print(random.random()) # random.random() 随机获取…

NodeJS入门04-Express路由和中间件 - 小之 - 博客园

nodeJS入门04-Express路由和中间件 Express框架是后台的Node框架&#xff0c;在后台的受欢迎的程度&#xff0c;和jQuery一样&#xff0c;就是企业的事实上的标准。 路由 路由是指如何定义应用的端点&#xff08;URIs&#xff09;以及如何响应客户端的请求。 路由是由一个 …

jmeter(四十五)常用Beanshell脚本

整理了一批jmeter常用的beanshell脚本供大家参考&#xff01; 时间戳 import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; try{ Date date new Date(); //获取当前时间 SimpleDateFormat sf new SimpleDateFormat("yyyy-MM-dd HH:mm…

Critical error detected c0000374

我发现出现上述错误是 free 两次内存 float* ddnew float[2];delete[] dd;delete[] dd;转载于:https://www.cnblogs.com/hook-gou/p/9994662.html

nodejs开发 过程中express路由与中间件的理解 - pyj063 - 博客园

nodejs开发 过程中express路由与中间件的理解 nodejs开发 express路由与中间件 路由 通常HTTP URL的格式是这样的&#xff1a; http://host[:port][path] http表示协议。 host表示主机。 port为端口&#xff0c;可选字段&#xff0c;不提供时默认为80。 path指定请求资源的…

错误MSB4018 “ResolvePackageAssets”任务意外失败的解决方法

昨天系统奔溃了&#xff0c;重装系统后发现&#xff0c;之前写的.netcore项目打开后重新生成报错&#xff0c;错误如下严重性 代码 说明 项目 文件 行 禁止显示状态 错误 MSB4018 “ResolvePackageAssets”任务意外失败。 NuGet.Packaging.Core.Packag…

(五)Unity插件生成

1&#xff09;新建空的AndroidStudio工程&#xff0c;但是新建过程时最小SDK版本要与unity一致&#xff0c;如下图所示&#xff0c;本次操作均为api16 2&#xff09;创建Library&#xff0c;如下图所示&#xff0c;新建module&#xff0c;然后选择Android Library。 新建模块为…

centeros7安装mysql - 风中追风_lonely - 博客园

转载自&#xff1a;https://www.linuxidc.com/Linux/2016-09/135288.htm 安装之前先安装基本环境&#xff1a;yum install -y perl perl-Module-Build net-tools autoconf libaio numactl-libs 1、配置YUM源 在MySQL官网中下载YUM源rpm安装包&#xff1a;http://dev.mysql.c…

失物招领平台6

昨天做了什么&#xff1a;学习了复选框、列表视图、网络视图&#xff0c;集体讨论了登录页面的构思 今天准备做什么&#xff1a;继续学习Android stdio&#xff0c;改善登录页面 遇到的问题&#xff1a;时间远远不够。转载于:https://www.cnblogs.com/sljslj/p/11056074.html

前后端交互json字符串

//将需要的参数转成json字符串&#xff0c;然后用utf-8编码 var obj encodeURIComponent(JSON.stringify(this.categories),"utf-8") //后台将前台的json字符串按照utf-8的格式解码&#xff0c;然后进行转换 RequestMapping(value "/updateMaterialDemoInfo.d…

CSS布局解决方案(终结版)

前端布局非常重要的一环就是页面框架的搭建&#xff0c;也是最基础的一环。在页面框架的搭建之中&#xff0c;又有居中布局、多列布局以及全局布局&#xff0c;今天我们就来总结总结前端干货中的CSS布局。 居中布局 水平居中 1&#xff09;使用inline-blocktext-align &…

个人作业7 第一阶段SCRUM冲刺(七)

了解了一下云服务器&#xff0c;下载了阿里云。 然而搞了半天还是没应用上这个云服务器..转载于:https://www.cnblogs.com/jbwen/p/11071733.html

Dcloud HTML5 监听蓝牙设备 调用 原生安卓实现 - aspirant - 博客园

最近一直搞Dcloud &#xff0c;这是HTML5版本的开发&#xff0c;打包时候&#xff0c;可以打包成 apk 和ipa 分别运行在安卓和ios 机器上面&#xff0c; 但是这里面的资料很少&#xff0c;遇到问题&#xff0c;之后只能自己钻研总结&#xff0c; 现在有这么一个需求&#xff…

NOIP2018游记

NOIP 2018 游记 又是一年 \(NOIP\) 呢...第二次参加了,希望这一次能不再擦线吧...毕竟我真的很想去 \(WC\) ,也很想去省选. 最后悔的事就是在初三了,恰逢直升,大好年华,停课学 \(OI\) ,但我竟然在某两位 \(dalao\) 带领下搓了一年 炉石 \(\& \: SC2\) &#xff1f;&#xf…