我最近由于在做一個關(guān)于FTP文件上傳和下載的功能時候,,發(fā)現(xiàn)Apache FTP jar包沒有提供對整個目錄結(jié)構(gòu)的上傳和下載功能,只能非目錄類型的文件進行上傳和下載操作,,后來我查閱很多網(wǎng)上的實現(xiàn)方法,,再結(jié)合自己的理解、以及符合自己的需求,,完成了我自己的apache FTP jar包補充類,。
上面是背景,基本敘述完畢,,下面開始介紹實現(xiàn)方法和代碼,。
一。環(huán)境搭建:
1.使用的FileZilla Server開源免費軟件,,安裝過后建立的本地FTP服務(wù)器。
2.使用的apache上下載FTP工具包,,引用到工程目錄中,。
3.IDE,Eclipse,,JDK6
二,。介紹代碼。
上傳和下載目錄的實現(xiàn)原理:對每一個層級的目錄進行判斷,,是為目錄類型,、還是文件類型,。
如果為目錄類型,采用遞歸調(diào)用方法,,檢查到最底層的目錄為止結(jié)束,。
如果為文件類型,則調(diào)用上傳或者下載方法對文件進行上傳或者下載操作,。
貼出代碼:(其中有些沒有代碼,,可以看看,還是很有用處的)
- 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();
-
- /**
- * 本方法用戶登錄遠(yuǎn)程的FTP服務(wù)器
- *
- * @param url :表示FTP的IP地址
- * @param port :FTP服務(wù)器端口,,默認(rèn)端口為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 :是否已經(jīng)關(guān)閉連接
- *
- * @throws IOException
- */
- public static boolean closeConnections(FTPClient ftpc) throws IOException {
- boolean bool = false;
- ftpc.logout();
- return bool;
- }
-
- /**
- * 方法用于上傳文件到FTP服務(wù)器的指定文件夾中
- *
- * @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");
- // 轉(zhuǎn)到上傳文件的FTP目錄中
- ftpClient.changeWorkingDirectory(toFtpPath);
- // 設(shè)置處理文件的類型為字節(jié)流的形式
- ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
- // 如果缺省該句 傳輸txt正常 但圖片和其他格式的文件傳輸出現(xiàn)亂碼
- ftpClient.storeFile(fileName, input);
- input.close();
- bool = true;
- } catch (IOException e) {
- bool = false;
- e.printStackTrace();
- }
- return bool;
- }
-
- /**
- * 方法用于從FTP服務(wù)器中下載文件
- *
- * @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[i].getName())) {
- ftpClient.retrieveFile(new String(ftpFile[i].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[i].getName())) {
- ftpClient.deleteFile(fileName);
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return bool;
- }
-
- /**
- * 判斷指定文件中是否存在相同名稱的文件
- *
- * @param remotePath :FTP上的遠(yuǎn)程目錄
- * @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[i].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上創(chuàng)建一個和File對象文件相同名稱的文件夾
- ftpClient.makeDirectory(toRemotePath+"http://"+dirFile.getName());
- //獲得File對象中包含的子目錄數(shù)組
- File[] subFiles = dirFile.listFiles();
- //路徑
- String path = toRemotePath+"http://"+dirFile.getName();
- System.out.println(path);
- //判斷數(shù)組是否為空
- if (subFiles!=null && subFiles.length>0) {
- //遍歷整個File數(shù)組
- for (int i = 0; i < subFiles.length; i++) {
- //判斷是否為目錄類型
- if (subFiles[i].isDirectory()) {
- //如果為目錄類型
- //跳轉(zhuǎn)到FTP的根目錄層級
- ftpClient.changeWorkingDirectory("http://");
- //在FTP上建立相同的目錄名稱
- ftpClient.makeDirectory(path+"http://"+subFiles[i].getName());
- //遞歸調(diào)用自身方法,進行到下一層級的目錄循環(huán)
- uploadDirFiles(subFiles[i].getAbsolutePath(), path);
- } else {
- //如果為文件類型
- //建立一個文件輸出流對象
- FileInputStream input = new FileInputStream(subFiles[i]);
- //調(diào)用文件上傳方法,,將文件上傳到FTP上
- uploadFileToFtp(subFiles[i].getName(), input, path+"http://");
- //關(guān)閉文件輸入流
- input.close();
- }
- }
- }
- } else {
- //如果為文件類型
- //建立一個文件輸出流對象
- FileInputStream input = new FileInputStream(dirFile);
- //調(diào)用文件上傳方法,,將文件上傳到FTP上
- uploadFileToFtp(dirFile.getName(), input, toRemotePath);
- //關(guān)閉文件輸入流
- input.close();
- }
- }
- }
-
- //本方法用于下載FTP上的目錄結(jié)構(gòu)到本地中
- 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對象數(shù)組
- 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[i];
- //判斷是否為目錄結(jié)構(gòu)
- if (subFile.isDirectory()) {
- //如果為目錄結(jié)構(gòu)
- //調(diào)用自身方法,進行下一層級目錄循環(huán)
- downloadDirFiles(remotePath+"http://"+subFile.getName(), localPath, subFile.getName());
- } else {
- //如果不為目錄結(jié)構(gòu),為文件類型
- FileOutputStream outputStream = new FileOutputStream(new File(localPath+"\\"+subFile.getName()));
- //調(diào)用下載方法對文件進行下載
- downloadFileFromFtp(remotePath, subFile.getName(), outputStream);
- //關(guān)閉文件輸出流
- outputStream.close();
- }
- }
- }
- }
- }
- }
編寫一個測試main類,,進行測試,。
- 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", "http://");
- } 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();
- }
- }
有什么更好地建議或者方法,請直接評論回答,。
===============Over========================
|