欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java语言实现简单FTP软件 FTP上传下载管理模块实现(11)

程序员文章站 2024-03-03 20:52:40
本文为大家分享了ftp上传下载管理模块的实现方法,供大家参考,具体内容如下 1、上传本地文件或文件夹到远程ftp服务器端的功能。 当用户在本地文件列表中选择想要上传...

本文为大家分享了ftp上传下载管理模块的实现方法,供大家参考,具体内容如下

1、上传本地文件或文件夹到远程ftp服务器端的功能。

当用户在本地文件列表中选择想要上传的文件后,点击上传按钮,将本机上指定的文件上传到ftp服务器当前展现的目录,下图为上传子模块流程图

Java语言实现简单FTP软件 FTP上传下载管理模块实现(11)

选择好要上传的文件或文件夹,点击“上传”按钮,会触发com.oyp.ftp.panel.local.uploadaction类的actionperformed(actionevent e)方法,其主要代码如下

/** 
 * 上传文件动作的事件处理方法 
 */ 
public void actionperformed(java.awt.event.actionevent evt) { 
 // 获取用户选择的多个文件或文件夹 
 int[] selrows = this.localpanel.localdisktable.getselectedrows(); 
 if (selrows.length < 1) { 
  joptionpane.showmessagedialog(this.localpanel, "请选择上传的文件或文件夹"); 
  return; 
 } 
 // 获取ftp服务器的当前路径 
 string pwd = this.localpanel.frame.getftppanel().getpwd(); 
 // 创建ftp当前路径的文件夹对象 
 ftpfile ftpfile = new ftpfile("", pwd, true); 
 // 遍历本地资源的表格 
 for (int i = 0; i < selrows.length; i++) { 
  object valueat = this.localpanel.localdisktable.getvalueat( 
    selrows[i], 0); // 获取表格选择行的第一列数据 
  if (valueat instanceof diskfile) { 
   final diskfile file = (diskfile) valueat; 
   // 获取本地面板类中的队列,该队列是linkedlist类的实例对象 
   queue<object[]> queue = this.localpanel.queue; 
   queue.offer(new object[] { file, ftpfile });// 执行offer方法向队列尾添加对象 
  } 
 } 
} 

在com.oyp.ftp.panel.local.uploadthread线程类的run()方法,会判断上传队列是否有对象,如果有则调用其copyfile(file file, ftpfile ftpfile)方法实现上传文件的功能,上传完后刷新远程ftp文件管理的面板。其run()方法主要代码如下

 * 线程的主体方法 
 */ 
public void run() { // 线程的主体方法 
 while (conrun) { 
  try { 
   thread.sleep(1000); // 线程休眠1秒 
   queue<object[]> queue = localpanel.queue; // 获取本地面板的队列对象 
   queuevalues = queue.peek(); // 获取队列首的对象 
   if (queuevalues == null) { // 如果该对象为空 
    continue; // 进行下一次循环 
   } 
   file file = (file) queuevalues[0]; // 获取队列中的本队文件对象 
   ftpfile ftpfile = (ftpfile) queuevalues[1]; // 获取队列中的ftp文件对象 
   if (file != null) { 
    selpath = file.getparent(); 
    copyfile(file, ftpfile); // 调用递归方法上传文件 
    ftppanel ftppanel = localpanel.frame.getftppanel(); 
    ftppanel.refreshcurrentfolder(); // 刷新ftp面板中的资源 
   } 
   object[] args = queue.peek(); 
   // 判断队列顶是否为处理的上一个任务。 
   if (queuevalues == null || args == null 
     || !queuevalues[0].equals(args[0])) { 
    continue; 
   } 
   queue.remove(); // 移除队列首元素 
  } catch (exception e) { 
   e.printstacktrace(); 
  } 
 } 
} 

其中调用的copyfile(file file, ftpfile ftpfile)方法代码如下

  /** 
  * 上传线程的递归方法,上传文件夹的所有子文件夹和内容 
  * @param file 
  *   - ftp文件对象 
  * @param localfolder 
  *   - 本地文件夹对象 
  */ 
 private void copyfile(file file, ftpfile ftpfile) { // 递归遍历文件夹的方法 
  // 判断队列面板是否执行暂停命令 
  while (localpanel.frame.getqueuepanel().isstop()) { 
   try { 
    thread.sleep(1000); 
   } catch (interruptedexception e) { 
    e.printstacktrace(); 
   } 
  } 
 
  object[] args = localpanel.queue.peek(); 
  // 判断队列顶是不是上一个处理的任务。 
  if (queuevalues == null || args == null 
    || !queuevalues[0].equals(args[0])) 
   return; 
  try { 
//   system.out.println("selpath:"+selpath); 
   path = file.getparentfile().getpath().replace(selpath, ""); 
//   system.out.println("path:"+path); 
   ftpfile.setname(path.replace("\\", "/")); 
   path = ftpfile.getabsolutepath(); 
//   system.out.println("ftpfile.getabsolutepath():"+path); 
   if (file.isfile()) { 
    uploadpanel uploadpanel = localpanel.frame.getuploadpanel();//上传面板 
    string remotefile = path + "/" + file.getname(); // 远程ftp的文件名绝对路径 
//    system.out.println("remotefile:" + remotefile); 
    double filelength = file.length() / math.pow(1024, 2); 
    progressarg progressarg = new progressarg( 
      (int) (file.length() / 1024), 0, 0);//进度参数 
    string size = string.format("%.4f mb", filelength); 
    object[] row = new object[] { file.getabsolutefile(), size, 
      remotefile, ftpclient.getserver(), progressarg }; 
    uploadpanel.addrow(row); //添加列 
    outputstream put = ftpclient.put(remotefile); // 获取服务器文件的输出流 
    fileinputstream fis = null; // 本地文件的输入流 
    try { 
     fis = new fileinputstream(file); // 初始化文件的输入流 
    } catch (exception e) { 
     e.printstacktrace(); 
     return; 
    } 
    int readnum = 0; 
    byte[] data = new byte[1024]; // 缓存大小 
    while ((readnum = fis.read(data)) > 0) { // 读取本地文件到缓存 
     thread.sleep(0, 30); // 线程休眠 
     put.write(data, 0, readnum); // 输出到服务器 
     progressarg.setvalue(progressarg.getvalue() + 1);// 累加进度条 
    } 
    progressarg.setvalue(progressarg.getmax()); // 结束进度条 
    fis.close(); // 关闭文件输入流 
    put.close(); // 关闭服务器输出流 
   } else if (file.isdirectory()) { 
    path = file.getpath().replace(selpath, ""); 
    ftpfile.setname(path.replace("\\", "/")); 
//    system.out.println("dirpath:"+path); 
    /**将目录切换到当前ftp服务器的当前目录*/ 
    ftpclient.cd(this.localpanel.frame.getftppanel().getpwd());  // /media目录 
    /** 
     * 如果有创建文件夹的权限,则在当前ftp服务器的当前目录下创建文件夹 
     * 必须要有创建文件夹的权限,否则会报错 
     *  path:audio 
      ftpfile.getabsolutepath():/media/audio 
      remotefile:/media/audio/梁静茹-会呼吸的痛live.mp3 
     */ 
    ftpclient.sendserver("mkd " + path + "\r\n"); //创建 /media/audio 目录 
    ftpclient.readserverresponse(); 
     
    /*********************************************************** 
     * 如果没有有创建文件夹的权限,则创建文件夹,因此ftp服务器的当前路径下不存在 
     * 那么将文件上传到此ftp服务器的当前路径下 
     * 
     *  如要上传c://audio目录(目录中有 梁静茹-会呼吸的痛live.mp3 和 林宥嘉-心酸.mp3 两个文件) 
     *  到 ftp服务器上的 /media/ 目录下 
     *  因为ftp服务器上没有 /media/audio 目录,并且ftp服务器当前的目录为 /media 
     *  所以将 c://audio目录下的文件上传到了 /media目录下 
     *  ftpfile.getabsolutepath():/media/audio 
      remotefile:/media/梁静茹-会呼吸的痛live.mp3 
      remotefile:/media/林宥嘉-心酸.mp3 
     */ 
    //创建一个文件夹对象,检查该文件是否存在 
    file fileremote=new file(this.localpanel.frame.getftppanel().getpwd()+path); //path:audio 
    //该目录不存在 
    if (!fileremote.exists()) { 
     path=this.localpanel.frame.getftppanel().getpwd(); 
    } 
    /***********************************************************/ 
     
    file[] listfiles = file.listfiles(); 
    for (file subfile : listfiles) { 
     thread.sleep(0, 50); 
     copyfile(subfile, ftpfile); 
    } 
   } 
  } catch (filenotfoundexception e1) { 
   e1.printstacktrace(); 
   system.exit(0); 
   // joptionpane.showmessagedialog(localpanel, e1.getmessage()); 
  } catch (exception ex) { 
   ex.printstacktrace(); 
  } 
 } 

2、下载远程ftp服务器端的文件或文件夹到本地

当用户在远程ftp服务器文件列表中选择想要下载的文件后,点击下载按钮,将服务器上的文件下载至本机,下图为下载子模块流程图。

Java语言实现简单FTP软件 FTP上传下载管理模块实现(11)

选择好要下载的文件或文件夹,点击“下载”按钮,会触发com.oyp.ftp.panel.ftp.downaction类的actionperformed(actionevent e)方法,其主要代码如下

  /** 
  * 下载按钮的动作处理器动作的事件处理方法 
 */ 
@override 
public void actionperformed(actionevent e) { 
 // 获取ftp资源表格的所有选择行 
 final int[] selrows = ftppanel.ftpdisktable.getselectedrows(); 
 if (selrows.length < 1) 
  return; 
 // 遍历表格的所有选择行 
 for (int i = 0; i < selrows.length; i++) { 
  // 获取每行的第一个单元值并转换成ftpfile类的对象 
  final ftpfile file = (ftpfile) ftppanel.ftpdisktable.getvalueat( 
    selrows[i], 0); 
  if (file != null) { 
   // 获取本地资源管理面板的当前文件夹 
   file currentfolder = ftppanel.frame.getlocalpanel() 
     .getcurrentfolder(); 
   // 把ftp文件对象和本地当前文件夹对象定义成数组添加到下载队列中 
   ftppanel.queue.offer(new object[] { file, currentfolder }); 
  } 
 } 
} 

在com.oyp.ftp.panel.ftp.downthread线程类的run()方法,会判断下载队列是否有对象,如果有则调用其downfile(ftpfile file, file localfolder)方法实现上传文件的功能,上传完后刷新远程ftp文件管理的面板。其run()方法代码如下

public void run() { // 线程业务方法 
  while (conrun) { 
   try { 
    thread.sleep(1000); 
    ftpclient.noop(); 
    queuevalues = ftppanel.queue.peek(); 
    if (queuevalues == null) { 
     continue; 
    } 
    ftpfile file = (ftpfile) queuevalues[0]; 
    file localfolder = (file) queuevalues[1]; 
    if (file != null) { 
     path = file.getpath(); 
     ftpclient.cd(path); 
     downfile(file, localfolder); 
     path = null; 
     ftppanel.frame.getlocalpanel().refreshcurrentfolder(); 
    } 
    object[] args = ftppanel.queue.peek(); 
    // 判断队列顶是否为处理的上一个任务。 
    if (queuevalues == null || args == null 
      || !queuevalues[0].equals(args[0])) 
     continue; 
    ftppanel.queue.poll(); 
   } catch (exception e) { 
    e.printstacktrace(); 
   } 
  } 
 } 

其中调用的downfile(ftpfile file, file localfolder)方法代码如下

/** 
  * 下载线程的递归方法,用户探索ftp下载文件夹的所有子文件夹和内容 
  * @param file ftp文件对象 
  * @param localfolder 本地文件夹对象 
  */ 
 private void downfile(ftpfile file, file localfolder) { 
  // 判断队列面板是否执行暂停命令 
  while (ftppanel.frame.getqueuepanel().isstop()) { 
   try { 
    thread.sleep(1000); 
   } catch (interruptedexception e) { 
    e.printstacktrace(); 
   } 
  } 
  object[] args = ftppanel.queue.peek(); 
  // 判断队列顶是否为处理的上一个任务。 
  if (queuevalues == null || args == null 
    || !queuevalues[0].equals(args[0])) 
   return; 
  try { 
   string ftpfilestr = file.getabsolutepath().replacefirst(path + "/", 
     ""); 
   if (file.isfile()) { 
    // 获取服务器指定文件的输入流 
    telnetinputstream ftpis = ftpclient.get(file.getname()); 
    if (ftpis == null) { 
     joptionpane.showmessagedialog(this.ftppanel, file.getname() 
       + "无法下载"); 
     return; 
    } 
    // 创建本地文件对象 
    file downfile = new file(localfolder, ftpfilestr); 
    // 创建本地文件的输出流 
    fileoutputstream fout = new fileoutputstream(downfile, true); 
    // 计算文件大小 
    double filelength = file.getlongsize() / math.pow(1024, 2); 
    progressarg progressarg = new progressarg((int) (file 
      .getlongsize() / 1024), 0, 0); //进度参数 
    string size = string.format("%.4f mb", filelength); 
    //"文件名", "大小", "本地文件名","主机", "状态" 
    object[] row = new object[] { ftpfilestr, size, 
      downfile.getabsolutepath(), ftpclient.getserver(), 
      progressarg }; 
    downloadpanel downloadpanel = ftppanel.frame.getdownloadpanel(); //下载队列面板 
    downloadpanel.addrow(row); //添加列 
    byte[] data = new byte[1024]; // 定义缓存 
    int read = -1; 
    while ((read = ftpis.read(data)) > 0) { // 读取ftp文件内容到缓存 
     thread.sleep(0, 30); // 线程休眠 
     fout.write(data, 0, read); // 将缓存数据写入本地文件 
     // 累加进度条 
     progressarg.setvalue(progressarg.getvalue() + 1); 
    } 
    progressarg.setvalue(progressarg.getmax());// 结束进度条 
    fout.close(); // 关闭文件输出流 
    ftpis.close(); // 关闭ftp文件输入流 
   } else if (file.isdirectory()) { // 如果下载的是文件夹 
    // 创建本地文件夹对象 
    file directory = new file(localfolder, ftpfilestr); 
    directory.mkdirs(); // 创建本地的文件夹 
    ftpclient.cd(file.getname()); // 改变ftp服务器的当前路径 
    // 获取ftp服务器的文件列表信息 
    telnetinputstream telnetinputstream=ftpclient.list(); 
    byte[]names=new byte[2048]; 
    int bufsize=0; 
    bufsize=telnetinputstream.read(names, 0, names.length); 
    int i=0,j=0; 
    while(i<bufsize){ 
     //字符模式为10,二进制模式为13 
//     if (names[i]==10) { 
     if (names[i]==13) { 
      //获取字符串 -rwx------ 1 user group   57344 apr 18 05:32 腾讯电商2013实习生招聘tst推荐模板.xls 
      //文件名在数据中开始做坐标为j,i-j为文件名的长度,文件名在数据中的结束下标为i-1 
      string filemessage = new string(names,j,i-j); 
      if(filemessage.length() == 0){ 
       system.out.println("filemessage.length() == 0"); 
       break; 
      } 
      //按照空格将filemessage截为数组后获取相关信息 
      // 正则表达式 \s表示空格,{1,}表示1一个以上 
      if(!filemessage.split("\\s+")[8].equals(".") && !filemessage.split("\\s+")[8].equals("..")){ 
       /**文件大小*/ 
       string sizeordir=""; 
       if (filemessage.startswith("d")) {//如果是目录 
        sizeordir="<dir>"; 
       }else if (filemessage.startswith("-")) {//如果是文件 
        sizeordir=filemessage.split("\\s+")[4]; 
       } 
       /**文件名*/ 
       string filename=filemessage.split("\\s+")[8]; 
       ftpfile ftpfile = new ftpfile(); 
       // 将ftp目录信息初始化到ftp文件对象中 
       ftpfile.setsize(sizeordir); 
       ftpfile.setname(filename); 
       ftpfile.setpath(file.getabsolutepath()); 
       // 递归执行子文件夹的下载 
       downfile(ftpfile, localfolder); 
      } 
//      j=i+1;//上一次位置为字符模式 
      j=i+2;//上一次位置为二进制模式 
     } 
     i=i+1; 
    } 
    ftpclient.cdup(); // 返回ftp上级路径 
   } 
  } catch (exception ex) { 
   ex.printstacktrace(); 
  } 
 } 

功能效果图可以查看以下两篇文章。

java语言实现简单ftp软件------>ftp软件效果图预览之上传功能(三)

java语言实现简单ftp软件------>ftp软件效果图预览之下载功能(二)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。