使用递归方法实现,向FTP服务器上传整个目录结构、从FTP服务器下载整个目录到本地的功能
我最近由于在做一个关于FTP文件上传和下载的功能时候,发现Apache FTP jar包没有提供对整个目录结构的上传和下载功能,只能非目录类型的文件进行上传和下载操作,后来我查阅很多网上的实现方法,再结合自己的理解、以及符合自己的需求,完成了我自己的apache FTP jar包补充类。上面是背景,基本叙述完毕,下面开始介绍实现方法和代码。
一。环境搭建:
1.使用的FileZilla Server开源免费软件,安装过后建立的本地FTP服务器。
2.使用的apache上下载FTP工具包,引用到工程目录中。
3.IDE,Eclipse,JDK6
二。介绍代码。
上传和下载目录的实现原理:对每一个层级的目录进行判断,是为目录类型、还是文件类型。
如果为目录类型,采用递归调用方法,检查到最底层的目录为止结束。
如果为文件类型,则调用上传或者下载方法对文件进行上传或者下载操作。
贴出代码:(其中有些没有代码,可以看看,还是很有用处的)
view plaincopyprint?
[*]package com.ftp;
[*]
[*]import java.io.File;
[*]import java.io.FileInputStream;
[*]import java.io.FileOutputStream;
[*]import java.io.IOException;
[*]import java.io.InputStream;
[*]import java.io.OutputStream;
[*]import java.net.SocketException;
[*]
[*]import org.apache.commons.net.ftp.FTP;
[*]import org.apache.commons.net.ftp.FTPClient;
[*]import org.apache.commons.net.ftp.FTPClientConfig;
[*]import org.apache.commons.net.ftp.FTPFile;
[*]import org.apache.commons.net.ftp.FTPReply;
[*]
[*]public class RemoteFtpProcess extends FTPClient {
[*] private static FTPClient ftpClient = new FTPClient();
[*]
[*] /**
[*] * 本方法用户登录远程的FTP服务器
[*] *
[*] * @param url :表示FTP的IP地址
[*] * @param port :FTP服务器端口,默认端口为21
[*] * @param userName :登录FTP的用户名
[*] * @param password :登录FTP的密码
[*] *
[*] * @return FTPClient:返回为FTPClient对象
[*] */
[*] public FTPClient loginFtp(String url, int port, String userName,
[*] String password) {
[*] try {
[*] ftpClient.connect(url, port);
[*] ftpClient.setControlEncoding("UTF-8");
[*] FTPClientConfig ftpConfig = new FTPClientConfig(FTPClientConfig.SYST_NT);
[*] ftpConfig.setServerLanguageCode("zh");
[*] ftpClient.login(userName, password);
[*] int reply = 0;
[*] reply = ftpClient.getReplyCode();
[*] System.out.println(reply);
[*] if (FTPReply.isPositiveCompletion(reply)) {
[*] System.out.println("登录成功!");
[*] } else {
[*] System.out.println("登录失败!");
[*] }
[*] } catch (SocketException e) {
[*] e.printStackTrace();
[*] } catch (IOException e) {
[*] e.printStackTrace();
[*] }
[*] return ftpClient;
[*] }
[*]
[*] /**
[*] * @param ftpc :退出FTP登录
[*] * @return boolean :是否已经关闭连接
[*] *
[*] * @throws IOException
[*] */
[*] public static boolean closeConnections(FTPClient ftpc) throws IOException {
[*] boolean bool = false;
[*] ftpc.logout();
[*] return bool;
[*] }
[*]
[*] /**
[*] * 方法用于上传文件到FTP服务器的指定文件夹中
[*] *
[*] * @param fileName :上传文件的名称
[*] * @param input :上传文件的输入流对象
[*] * @param toFtpPath :上传到FTP的目的路径
[*] *
[*] * @return boolean:表示上传是否成功
[*] *
[*] */
[*] public boolean uploadFileToFtp(String fileName, InputStream input,
[*] String toFtpPath) {
[*] boolean bool = false;
[*] try {
[*] // 使得能够处理中文编码
[*] fileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");
[*] toFtpPath = new String(toFtpPath.getBytes("GBK"), "ISO-8859-1");
[*] // 转到上传文件的FTP目录中
[*] ftpClient.changeWorkingDirectory(toFtpPath);
[*] // 设置处理文件的类型为字节流的形式
[*] ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
[*] // 如果缺省该句 传输txt正常 但图片和其他格式的文件传输出现乱码
[*] ftpClient.storeFile(fileName, input);
[*] input.close();
[*] bool = true;
[*] } catch (IOException e) {
[*] bool = false;
[*] e.printStackTrace();
[*] }
[*] return bool;
[*] }
[*]
[*] /**
[*] * 方法用于从FTP服务器中下载文件
[*] *
[*] * @param ftpUrl :下载文件所处FTP中路径
[*] * @param fileName :下载的文件名称
[*] * @param outputSream :下载文件的输出流对象
[*] *
[*] * @return boolean :表示是否上传成功
[*] *
[*] */
[*] public boolean downloadFileFromFtp(String ftpUrl, String fileName,
[*] OutputStream outputStream) {
[*] boolean bool = false;
[*] try {
[*] ftpClient.changeWorkingDirectory(ftpUrl);
[*] FTPFile[] ftpFile = ftpClient.listFiles();
[*] for (int i = 0; i < ftpFile.length; i++) {
[*] if (fileName.equals(ftpFile.getName())) {
[*] ftpClient.retrieveFile(new String(ftpFile.getName()
[*] .getBytes("GBK"), "ISO-8859-1"), outputStream);
[*] outputStream.flush();
[*] outputStream.close();
[*] }
[*] }
[*] bool = true;
[*] } catch (IOException e) {
[*] e.printStackTrace();
[*] bool = false;
[*] }
[*] return bool;
[*] }
[*]
[*] /**
[*] * 方法用户删除FTP上的指定的文件
[*] *
[*] * @param fileUrl :文件在FTP中的路径
[*] * @param fileName :文件的名称
[*] *
[*] * @return boolean:删除是否成功
[*] */
[*] public boolean deleteFileOnFtp(String fileUrl, String fileName) {
[*] boolean bool = false;
[*] try {
[*] ftpClient.changeWorkingDirectory(fileUrl);
[*] FTPFile[] ftpFiles = ftpClient.listFiles();
[*] System.out.println(ftpFiles.length);
[*] for (int i = 0; i < ftpFiles.length; i++) {
[*] if (fileName.equals(ftpFiles.getName())) {
[*] ftpClient.deleteFile(fileName);
[*] }
[*] }
[*] } catch (IOException e) {
[*] e.printStackTrace();
[*] }
[*] return bool;
[*] }
[*]
[*] /**
[*] * 判断指定文件中是否存在相同名称的文件
[*] *
[*] * @param remotePath :FTP上的远程目录
[*] * @param fileName:文件名称
[*] * @return boolean :判断是否存在相同名称
[*] *
[*] */
[*] public boolean isSameName(String remotePath, String fileName) {
[*] boolean bool = false;
[*] try {
[*] FTPFile[] ftpFiles = ftpClient.listFiles();
[*] System.out.println(ftpFiles.length);
[*] ftpClient.changeWorkingDirectory(remotePath);
[*] for (int i = 0; i < ftpFiles.length; i++) {
[*] if (fileName.equals(ftpFiles.getName())) {
[*] System.out.println("存在和指定文件相同名称的文件");
[*] bool = true;
[*] } else {
[*] bool = false;
[*] }
[*] }
[*] } catch (Exception e) {
[*] bool = false;
[*] }
[*] return bool;
[*] }
[*]
[*] /**
[*] * 更改文件名称
[*] *
[*] */
[*] public String changeName(String remotePath, String fileName, String newName) {
[*] if (isSameName(remotePath, fileName)) {
[*] fileName = fileName + "." + newName;
[*] }
[*] return fileName;
[*] }
[*]
[*]
[*] public static void newFileOnFTP(String pathName){
[*] try {
[*] ftpClient.mkd(pathName);
[*] } catch (IOException e) {
[*] e.printStackTrace();
[*] }
[*] }
[*]
[*] //上传整个目录到FTP的指定目录中
[*] public void uploadDirFiles(String dirPath,String toRemotePath) throws IOException{
[*] if (dirPath!=null && !dirPath.equals("")) {
[*] //建立上传目录的File对象
[*] File dirFile = new File(dirPath);
[*] //判断File对象是否为目录类型
[*] if (dirFile.isDirectory()) {
[*] //如果是目录类型。
[*] //在FTP上创建一个和File对象文件相同名称的文件夹
[*] ftpClient.makeDirectory(toRemotePath+"//"+dirFile.getName());
[*] //获得File对象中包含的子目录数组
[*] File[] subFiles = dirFile.listFiles();
[*] //路径
[*] String path = toRemotePath+"//"+dirFile.getName();
[*] System.out.println(path);
[*] //判断数组是否为空
[*] if (subFiles!=null && subFiles.length>0) {
[*] //遍历整个File数组
[*] for (int i = 0; i < subFiles.length; i++) {
[*] //判断是否为目录类型
[*] if (subFiles.isDirectory()) {
[*] //如果为目录类型
[*] //跳转到FTP的根目录层级
[*] ftpClient.changeWorkingDirectory("//");
[*] //在FTP上建立相同的目录名称
[*] ftpClient.makeDirectory(path+"//"+subFiles.getName());
[*] //递归调用自身方法,进行到下一层级的目录循环
[*] uploadDirFiles(subFiles.getAbsolutePath(), path);
[*] } else {
[*] //如果为文件类型
[*] //建立一个文件输出流对象
[*] FileInputStream input = new FileInputStream(subFiles);
[*] //调用文件上传方法,将文件上传到FTP上
[*] uploadFileToFtp(subFiles.getName(), input, path+"//");
[*] //关闭文件输入流
[*] input.close();
[*] }
[*] }
[*] }
[*] } else {
[*] //如果为文件类型
[*] //建立一个文件输出流对象
[*] FileInputStream input = new FileInputStream(dirFile);
[*] //调用文件上传方法,将文件上传到FTP上
[*] uploadFileToFtp(dirFile.getName(), input, toRemotePath);
[*] //关闭文件输入流
[*] input.close();
[*] }
[*] }
[*] }
[*]
[*] //本方法用于下载FTP上的目录结构到本地中
[*] public void downloadDirFiles(String remotePath,String localPath,String fileName) throws IOException{
[*] if (remotePath!=null && !remotePath.equals("")) {
[*] //在本地建立一个相同的文件目录
[*] File localFile = new File(localPath+"\\"+fileName);
[*] localFile.mkdirs();
[*] //获得目录在本地的绝对路径
[*] localPath = localFile.getAbsolutePath();
[*] System.out.println(localPath);
[*] //获得FTPFile对象数组
[*] FTPFile[] ftpFiles = ftpClient.listFiles(new String(remotePath.getBytes("GBK"),"ISO-8859-1"));
[*] if (ftpFiles!=null && ftpFiles.length>0) {
[*] for (int i = 0; i < ftpFiles.length; i++) {
[*] FTPFile subFile = ftpFiles;
[*] //判断是否为目录结构
[*] if (subFile.isDirectory()) {
[*] //如果为目录结构
[*] //调用自身方法,进行下一层级目录循环
[*] downloadDirFiles(remotePath+"//"+subFile.getName(), localPath, subFile.getName());
[*] } else {
[*] //如果不为目录结构,为文件类型
[*] FileOutputStream outputStream = new FileOutputStream(new File(localPath+"\\"+subFile.getName()));
[*] //调用下载方法对文件进行下载
[*] downloadFileFromFtp(remotePath, subFile.getName(), outputStream);
[*] //关闭文件输出流
[*] outputStream.close();
[*] }
[*] }
[*] }
[*] }
[*] }
[*]}
编写一个测试main类,进行测试。
view plaincopyprint?
[*]package com.ftp;
[*]
[*]import java.io.IOException;
[*]
[*]import org.apache.commons.net.ftp.FTPClient;
[*]
[*]public class TestMain {
[*] public static void upload(){
[*] RemoteFtpProcess remote = new RemoteFtpProcess();
[*] FTPClient ftpClient = remote.loginFtp("127.0.0.1", 21, "root", "root");
[*] try {
[*] remote.uploadDirFiles("D:\\FTPTestA", "//");
[*] } catch (IOException e) {
[*] e.printStackTrace();
[*] }
[*] }
[*]
[*] public static void download(){
[*] RemoteFtpProcess remote = new RemoteFtpProcess();
[*] FTPClient ftpClient = remote.loginFtp("127.0.0.1", 21, "root", "root");
[*] try {
[*] remote.downloadDirFiles("\\FTPTest", "E://", "FTPTestB
[*]");
[*] } catch (IOException e) {
[*] e.printStackTrace();
[*] }
[*] }
[*]
[*] public static void main(String[] args) {
[*] download();
[*] }
[*]}
文章转自:http://blog.csdn.net/captaingan/article/details/6970332
页:
[1]