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

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

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

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

选择好要上传的文件或文件夹,点击“上传”按钮,会触发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服务器文件列表中选择想要下载的文件后,点击下载按钮,将服务器上的文件下载至本机,下图为下载子模块流程图。

选择好要下载的文件或文件夹,点击“下载”按钮,会触发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软件效果图预览之下载功能(二)

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

(0)

相关推荐

  • JAVA技术实现上传下载文件到FTP服务器(完整)

    具体详细介绍请看下文: 在使用文件进行交互数据的应用来说,使用FTP服务器是一个很好的选择.本文使用Apache Jakarta Commons Net(commons-net-3.3.jar) 基于FileZilla Server服务器实现FTP服务器上文件的上传/下载/删除等操作. 关于FileZilla Server服务器的详细搭建配置过程,详情请见 FileZilla Server安装配置教程 .之前有朋友说,上传大文件(几百M以上的文件)到FTP服务器时会重现无法重命名的问题,但本人亲

  • JAVA中使用FTPClient实现文件上传下载实例代码

    在java程序开发中,ftp用的比较多,经常打交道,比如说向FTP服务器上传文件.下载文件,本文给大家介绍如何利用jakarta commons中的FTPClient(在commons-net包中)实现上传下载文件. 一.上传文件 原理就不介绍了,大家直接看代码吧 /** * Description: 向FTP服务器上传文件 * @Version1.0 Jul 27, 2008 4:31:09 PM by 崔红保(cuihongbao@d-heaven.com)创建 * @param url F

  • Java中FTPClient上传中文目录、中文文件名乱码问题解决方法

    问题描述: 使用org.apache.commons.net.ftp.FTPClient创建中文目录.上传中文文件名时,目录名及文件名中的中文显示为"??". 原因: FTP协议里面,规定文件名编码为iso-8859-1,所以目录名或文件名需要转码. 解决方案: 1.将中文的目录或文件名转为iso-8859-1编码的字符.参考代码: 复制代码 代码如下: String name="目录名或文件名"; name=new String(name.getBytes(&qu

  • java判断ftp目录是否存在的方法

    本文为大家分享了java判断ftp目录是否存在的方法,供大家参考,具体内容如下 package com.soft4j.log4j; import java.io.IOException; import sun.net.ftp.FtpClient; public class FtpTest { static String middle_ftpServer = "10.103.2.250"; static String middle_user = "ora9iftp";

  • Java语言实现简单FTP软件 FTP软件本地窗口实现(5)

    本文为大家介绍了FTP软件本地窗口的实现方法,供大家参考,具体内容如下 1.首先看一下本地窗口的布局效果 2.看一下本地窗口实现的代码框架 3.本地窗口的具体实现代码LocalPanel.java package com.oyp.ftp.panel.local; import java.awt.Color; import java.awt.Desktop; import java.awt.Dimension; import java.awt.event.ItemEvent; import jav

  • java实现FTP文件上传与文件下载

    本文实例为大家分享了两种java实现FTP文件上传下载的方式,供大家参考,具体内容如下 第一种方式: package com.cloudpower.util; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import sun.net.TelnetInputStream; import sun.net.TelnetO

  • Java通过FTP服务器上传下载文件的方法

    对于使用文件进行交换数据的应用来说,使用FTP 服务器是一个很不错的解决方案. 关于FileZilla Server服务器的详细搭建配置过程,详情请见FileZilla Server安装配置教程.之前有朋友说,上传大文件(几百M以上的文件)到FTP服务器时会重现无法重命名的问题,但本人亲测上传2G的文件到FileZilla Server都没有该问题,朋友们可以放心使用该代码. FavFTPUtil.Java package com.favccxx.favsoft.util; import jav

  • java操作ftp下载文件示例

    复制代码 代码如下: /**     *      * JAVA操作 FTP 下载     * 文件下载.     *     */    private void ftpDownload()    {        FTPClient ftpClient = null;        InputStream input = null;        boolean loginFlag = false;        List<String> list = new ArrayList<S

  • Java语言实现简单FTP软件 FTP本地文件管理模块实现(9)

    本文为大家分享了FTP本地文件管理模块的实现方法,供大家参考,具体内容如下 首先看一下界面: 1.本地文件列表的显示功能 将本地的当前目录下所有文件显示出来,并显示文件的属性包括文件名.大小.日期.通过javax.swing.JTable()来显示具体的数据.更改当前文件目录会调用com.oyp.ftp.panel.local.LocalPanel类的listLocalFiles()方法,其主要代码如下 /** * 读取本地文件到表格的方法 */ private void listLocalFi

  • java使用ftp上传文件示例分享

    复制代码 代码如下: import java.io.ByteArrayInputStream;  import java.io.FileOutputStream;  import java.io.IOException;  import java.net.SocketException;  import java.text.SimpleDateFormat;  import java.util.Date; import org.apache.commons.io.IOUtils;  import

随机推荐