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软件效果图预览之下载功能(二)

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

以上是 Java语言实现简单FTP软件 FTP上传下载管理模块实现(11) 的全部内容, 来源链接: utcz.com/p/212056.html

回到顶部