虚位以待(AD)
虚位以待(AD)
首页 > 软件编程 > Java编程 > Java语言实现简单FTP软件 FTP上传下载管理模块实现(11)

Java语言实现简单FTP软件 FTP上传下载管理模块实现(11)
类别:Java编程   作者:码皇   来源:互联网   点击:

这篇文章主要为大家详细介绍了Java语言实现简单FTP软件,FTP本地文件管理模块的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文为大家分享了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 + "rn");
    //创建 /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软件效果图预览之下载功能(二)

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

相关热词搜索: Java FTP 上传 下载