FTP 上傳 下載工具類

FTP 上傳 下載工具類
一.FTP介紹:

FTP 是File Transfer Protocol(文件傳輸協議)的英文簡稱,而中文簡稱爲“文傳協議”。用於Internet上的控制文件的雙向傳輸。同時,它也是一個應用程序(Application)。基於不同的操作系統有不同的FTP應用程序,而所有這些應用程序都遵守同一種協議以傳輸文件。在FTP的使用當中,用戶經常遇到兩個概念:"下載"(Download)和"上傳"(Upload)。"下載"文件就是從遠程主機拷貝文件至自己的計算機上;"上傳"文件就是將文件從自己的計算機中拷貝至遠程主機上。用Internet語言來說,用戶可通過客戶機程序向(從)遠程主機上傳(下載)文件。   --  摘自百度百科

通過JAVA來支持FTP上傳或者下載,其實不是太複雜,建立連接,上傳,關閉連接,就這樣步驟,爲了方便以及代碼健壯性,當然需要分裝一些功能的,但是網也流傳着許多工具類,但是其中有些是不行的,大多數都是由於路徑的問題,上傳多次後就不行了,這裏就貼一下工具類,網上download下來,然後修改了一下。

廢話不多說,直接上代碼了:

import it.sauronsoftware.ftp4j.FTPClient;
import it.sauronsoftware.ftp4j.FTPException;
import it.sauronsoftware.ftp4j.FTPFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.Properties;

import org.springframework.util.StringUtils;

import com.ibm.icu.text.SimpleDateFormat;
/**
 * FTP文件處理工具類
 * @author yangnuo
 */
public class FTPUtils {
	private static FTPUtils ftp;
	/**
	 * FTP服務地址
	 */
	private static String ADDRESS = "";//PropUtils.getString("ftp_server_address");  http:\\192.168.1.42:21
	/**
	 * FTP登錄用戶名
	 */
	private static String USERNAME = ""; //PropUtils.getString("ftp_server_username");   nuohy
	/**
	 * FTP登錄密碼
	 */
	private static String PASSWORD = ""; //PropUtils.getString("ftp_server_password");   123456
	
	/** 
	 * 本地  掃描路徑   某個文件夾
	 */
	private static String PATH = ""; 
	
	
	
	/**
	 * 構造方法
	 */
	public FTPUtils() {
		initPath();
	}
	/**
	 * 實例化對象
	 * 
	 * @return
	 */
	public static FTPUtils getInstance() {
		if (ftp == null) {
			ftp = new FTPUtils();
		}
		return ftp;
	}
	/**
	 * 獲取FTP客戶端對象
	 * 
	 * @return
	 * @throws Exception
	 */
	public FTPClient getClient() throws Exception {
		FTPClient client = new FTPClient();
		client.setCharset("utf-8");
		client.setType(FTPClient.TYPE_BINARY);
		URL url = new URL(FTPUtils.ADDRESS);
		int port = url.getPort() < 1 ? 21 : url.getPort();
		client.connect(url.getHost(), port);
		client.login(FTPUtils.USERNAME, FTPUtils.PASSWORD);
		return client;
	}
	/**
	 * 註銷客戶端連接
	 * 
	 * @param client
	 *            FTP客戶端對象
	 * @throws Exception
	 */
	public void logout(FTPClient client) throws Exception {
		boolean f = true;
        if (client == null){
        	f = true;
        }
        	
        if (client.isConnected()) { 
            try {
                client.disconnect(true);
                f = true;
            } catch (Exception e) { 
                try {
                	 System.out.println("開始強制退出...");
                     client.disconnect(false); 
                } catch (Exception e1) { 
                        e1.printStackTrace();
                        f = false;
                } 
            } 
        }
        
		/*if (client != null) {
			try {
				// 有些FTP服務器未實現此功能,若未實現則會出錯
				client.logout(); // 退出登錄
			} catch (FTPException fe) {
				System.out.println("1推出出現異常,原因:["+fe.getMessage()+"]");
			} catch (Exception e) {
				System.out.println("2推出出現異常,原因:["+e.getMessage()+"]");
				throw e;
			} finally {
				if (client.isConnected()) { // 斷開連接
					client.disconnect(true);
				}
			}
		}*/
	}
	
	
	/**
	 * 創建目錄
	 * 
	 * @param client
	 *            FTP客戶端對象
	 * @param dir
	 *            目錄
	 * @throws Exception
	 */
	private void mkdirs(FTPClient client, String dir) throws Exception {
		if (dir == null) {
			return;
		}
		dir = dir.replace("//", "/");
		String[] dirs = dir.split("/");
		for (int i = 0; i < dirs.length; i++) {
			dir = dirs[i];
			if (!StringUtils.isEmpty(dir)) {
				if (!exists(client, dir)) {
					client.createDirectory(dir);
				}
				client.changeDirectory(dir);
			}
		}
	}
	/**
	 * 獲取FTP目錄
	 * 
	 * @param url
	 *            原FTP目錄
	 * @param dir
	 *            目錄
	 * @return
	 * @throws Exception
	 */
	private URL getURL(URL url, String dir) throws Exception {
		String path = url.getPath();
		if (!path.endsWith("/") && !path.endsWith("//")) {
			path += "/";
		}
		dir = dir.replace("//", "/");
		if (dir.startsWith("/")) {
			dir = dir.substring(1);
		}
		path += dir;
		return new URL(url, path);
	}
	/**
	 * 獲取FTP目錄
	 * 
	 * @param dir
	 *            目錄
	 * @return
	 * @throws Exception
	 */
	private URL getURL(String dir) throws Exception {
		return getURL(new URL(FTPUtils.ADDRESS), dir);
	}
	/**
	 * 判斷文件或目錄是否存在
	 * 
	 * @param client
	 *            FTP客戶端對象
	 * @param dir
	 *            文件或目錄
	 * @return
	 * @throws Exception
	 */
	private boolean exists(FTPClient client, String dir) throws Exception {
		return getFileType(client, dir) != -1;
	}
	/**
	 * 判斷當前爲文件還是目錄
	 * 
	 * @param client
	 *            FTP客戶端對象
	 * @param dir
	 *            文件或目錄
	 * @return -1、文件或目錄不存在 0、文件 1、目錄
	 * @throws Exception
	 */
	private int getFileType(FTPClient client, String dir) throws Exception {
		FTPFile[] files = null;
		try {
			files = client.list(dir);
		} catch (Exception e) {
			return -1;
		}
		
		if (files.length > 1) {
			return FTPFile.TYPE_DIRECTORY;
		} else if (files.length == 1) {
			FTPFile f = files[0];
			if (f.getType() == FTPFile.TYPE_DIRECTORY) {
				return FTPFile.TYPE_DIRECTORY;
			}
			String path = dir + "/" + f.getName();
			try {
				int len = client.list(path).length;
				if (len == 1) {
					return FTPFile.TYPE_DIRECTORY;
				} else {
					return FTPFile.TYPE_FILE;
				}
			} catch (Exception e) {
				return FTPFile.TYPE_FILE;
			}
		} else {
			try {
				client.changeDirectory(dir);
				client.changeDirectoryUp();
				return FTPFile.TYPE_DIRECTORY;
			} catch (Exception e) {
				return -1;
			}
		}
	}
	/**
	 * 上傳文件或目錄
	 * 
	 * @param dir
	 *            目標文件
	 * @param del
	 *            是否刪除源文件,默認爲false
	 * @param file
	 *            文件或目錄對象數組
	 * @throws Exception
	 */
	public void upload(String dir, boolean del, File... files) throws Exception {
		if (StringUtils.isEmpty(dir) || StringUtils.isEmpty(files)) {
			return;
		}
		FTPClient client = null;
		try {
			client = getClient();
			
			if(IsCreateDir(dir)){
				mkdirs(client, dir); // 創建文件
			}
			
			client.changeDirectory(dir);
			
			for (File file : files) {
				if (file.isDirectory()) { // 上傳目錄
					uploadFolder(client, getURL(dir), file, del);
				} else {
					client.upload(file); // 上傳文件
					if (del) { // 刪除源文件
						file.delete();
					}
				}
			}
		} finally {
			logout(client);
		}
	}
	/**
	 * 上傳文件或目錄
	 * 
	 * @param dir
	 *            目標文件
	 * @param files
	 *            文件或目錄對象數組
	 * @throws Exception
	 */
	public void upload(String dir, File... files) throws Exception {
		upload(dir, false, files);
	}
	/**
	 * 上傳文件或目錄
	 * 
	 * @param dir
	 *            目標文件
	 * @param del
	 *            是否刪除源文件,默認爲false
	 * @param path
	 *            文件或目錄路徑數組
	 * @throws Exception
	 */
	public void upload(String dir, boolean del, String[] paths)throws Exception {
		if (StringUtils.isEmpty(paths)) {
			return;
		}
		File[] files = new File[paths.length];
		for (int i = 0; i < paths.length; i++) {
			files[i] = new File(paths[i]);
		}
		upload(dir, del, files);
	}
	/**
	 * 上傳文件或目錄
	 * 
	 * @param dir
	 *            目標文件
	 * @param paths
	 *            文件或目錄路徑數組
	 * @throws Exception
	 */
	public void upload(String dir, String... paths) throws Exception {
		upload(dir, false, paths);
	}
	/**
	 * 上傳目錄
	 * 
	 * @param client
	 *            FTP客戶端對象
	 * @param parentUrl
	 *            父節點URL
	 * @param file
	 *            目錄
	 * @throws Exception
	 */
	private void uploadFolder(FTPClient client, URL parentUrl, File file,
			boolean del) throws Exception {
		client.changeDirectory(parentUrl.getPath());
		String dir = file.getName(); // 當前目錄名稱
		URL url = getURL(parentUrl, dir);
		if (!exists(client, url.getPath())) { // 判斷當前目錄是否存在
			client.createDirectory(dir); // 創建目錄
		}
		client.changeDirectory(dir);
		File[] files = file.listFiles(); // 獲取當前文件夾所有文件及目錄
		for (int i = 0; i < files.length; i++) {
			file = files[i];
			if (file.isDirectory()) { // 如果是目錄,則遞歸上傳
				uploadFolder(client, url, file, del);
			} else { // 如果是文件,直接上傳
				client.changeDirectory(url.getPath());
				client.upload(file);
				if (del) { // 刪除源文件
					file.delete();
				}
			}
		}
	}
	/**
	 * 刪除文件或目錄
	 * 
	 * @param dir
	 *            文件或目錄數組
	 * @throws Exception
	 */
	public void delete(String... dirs) throws Exception {
		if (StringUtils.isEmpty(dirs)) {
			return;
		}
		FTPClient client = null;
		try {
			client = getClient();
			int type = -1;
			for (String dir : dirs) {
				client.changeDirectory("/"); // 切換至根目錄
				type = getFileType(client, dir); // 獲取當前類型
				if (type == 0) { // 刪除文件
					client.deleteFile(dir);
				} else if (type == 1) { // 刪除目錄
					deleteFolder(client, getURL(dir));
				}
			}
		} finally {
			logout(client);
		}
	}
	/**
	 * 刪除目錄
	 * 
	 * @param client
	 *            FTP客戶端對象
	 * @param url
	 *            FTP URL
	 * @throws Exception
	 */
	private void deleteFolder(FTPClient client, URL url) throws Exception {
		String path = url.getPath();
		client.changeDirectory(path);
		FTPFile[] files = client.list();
		String name = null;
		for (FTPFile file : files) {
			name = file.getName();
			// 排除隱藏目錄
			if (".".equals(name) || "..".equals(name)) {
				continue;
			}
			if (file.getType() == FTPFile.TYPE_DIRECTORY) { // 遞歸刪除子目錄
				deleteFolder(client, getURL(url, file.getName()));
			} else if (file.getType() == FTPFile.TYPE_FILE) { // 刪除文件
				client.deleteFile(file.getName());
			}
		}
		client.changeDirectoryUp();
		client.deleteDirectory(url.getPath()); // 刪除當前目錄
	}
	/**
	 * 下載文件或目錄
	 * 
	 * @param localDir
	 *            本地存儲目錄
	 * @param dirs
	 *            文件或者目錄
	 * @throws Exception
	 */
	public void download(String localDir, String... dirs) throws Exception {
		if (StringUtils.isEmpty(dirs)) {
			return;
		}
		FTPClient client = null;
		try {
			client = getClient();
			File folder = new File(localDir);
			if (!folder.exists()) { // 如果本地文件夾不存在,則創建
				folder.mkdirs();
			}
			int type = -1;
			String localPath = null;
			for (String dir : dirs) {
				client.changeDirectory("/"); // 切換至根目錄
				type = getFileType(client, dir); // 獲取當前類型
				if (type == 0) { // 文件
					localPath = localDir + "/" + new File(dir).getName();
					client.download(dir, new File(localPath));
				} else if (type == 1) { // 目錄
					downloadFolder(client, getURL(dir), localDir);
				}
			}
		} finally {
			logout(client);
		}
	}
	/**
	 * 下載文件夾
	 * 
	 * @param client
	 *            FTP客戶端對象
	 * @param url
	 *            FTP URL
	 * @param localDir
	 *            本地存儲目錄
	 * @throws Exception
	 */
	private void downloadFolder(FTPClient client, URL url, String localDir) throws Exception {
		String path = url.getPath();
		client.changeDirectory(path);
		// 在本地創建當前下載的文件夾
		File folder = new File(localDir + "/" + new File(path).getName());
		if (!folder.exists()) {
			folder.mkdirs();
		}
		localDir = folder.getAbsolutePath();
		FTPFile[] files = client.list();
		String name = null;
		for (FTPFile file : files) {
			name = file.getName();
			// 排除隱藏目錄
			if (".".equals(name) || "..".equals(name)) {
				continue;
			}
			if (file.getType() == FTPFile.TYPE_DIRECTORY) { // 遞歸下載子目錄
				downloadFolder(client, getURL(url, file.getName()), localDir);
			} else if (file.getType() == FTPFile.TYPE_FILE) { // 下載文件
				client.download(name, new File(localDir + "/" + name));
			}
		}
		client.changeDirectoryUp();
	}
	/**
	 * 獲取目錄下所有文件
	 * 
	 * @param dir
	 *            目錄
	 * @return
	 * @throws Exception
	 */
	public String[] list(String dir) throws Exception {
		FTPClient client = null;
		try {
			client = getClient();
			client.changeDirectory(dir);
			String[] values = client.listNames();
			if (values != null) {
				// 將文件排序(忽略大小寫)
				Arrays.sort(values, new Comparator<String>(){
					public int compare(String val1, String val2) {
						return val1.compareToIgnoreCase(val2);
					}
				});
			}
			return values;
		} catch(FTPException fe) {
			// 忽略文件夾不存在的情況
			String mark = "code=550";
			if (fe.toString().indexOf(mark) == -1) {
				throw fe;
			}
		} finally {
			logout(client);
		}
		return new String[0];
	}
	
	
	/**
	 * 判斷是否存在文件夾
	 * @param dir
	 * @return
	 */
	public boolean IsCreateDir(String dir){
		FTPClient client = null;
		boolean f = false;
		try {
			client = getClient();
			
			try {
				client.changeDirectory(dir);
				client.changeDirectoryUp();
			}catch (Exception e) {
				f = true;
			}
			
		} catch (Exception e) {
		}finally{
			try {
				logout(client);
			} catch (Exception e) {
				System.out.println("判斷是否存在文件夾時,關閉連接失敗!");
			}
		}
		
		System.out.println("能否創建文件夾:"+f);
		return f;
	}
	
	
	
	
	
	
	/**
	 * 初始化路徑
	 */
	public void initPath(){
			if(!PATH.equals("")&&!ADDRESS.equals("")&&!USERNAME.equals("")&&!PASSWORD.equals("")){
				return;
			}
		
    		System.out.println("加載路徑");
    		InputStream in = this.getClass().getResourceAsStream("/App.properties");
    		Properties prop = new Properties(); 
    		try {
    				prop.load(in); 
    			} catch (IOException e) {
    				e.printStackTrace();
    				System.out.println("讀取配置文件失敗!");
    		}
    		
    		PATH = prop.getProperty("scanpath");
    		ADDRESS = prop.getProperty("address");
    		USERNAME = prop.getProperty("username");
    		PASSWORD = prop.getProperty("password");
    		
	}
	
	
	
	/**
	 * 獲取文件夾下 所有的文件路徑
	 * @param path
	 * @return
	 */
	public String[] getFilePath(String path){

		System.out.println("======");
		
		if(path==null||path.equals("")){
			System.out.println("PATH:"+PATH);
			path = PATH;
		}
		
		String[] refilepath = new String[0];
		try{
			File file = new File(path);
			File[] listFiles = file.listFiles();
			for (File f : listFiles) {
				if(f.isFile()){
					String filename = f.getName();
					String[] split = filename.split("_");
					String timestr = split[1];
					timestr = timestr.substring(0, 8);
					
					int currentTime  = Integer.parseInt(new SimpleDateFormat("yyyyMMdd").format(new Date()));
//					System.out.println("split.length>"+split.length);
					
					//只備份昨天的  數據
					if(Integer.parseInt(timestr)==currentTime-1&&split.length==2){
						refilepath = Arrays.copyOf(refilepath, refilepath.length+1);
						refilepath[refilepath.length-1] = f.getAbsolutePath();
					}
				}
			}
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("獲取路徑失敗!");
		}
		return refilepath;
	}
	

	
	/**
	 * 修改文件名字
	 * @return
	 */
	public boolean editFileName(String filepath,String newFileName){
		try{
			File file = new File(filepath);
			file.renameTo(new File(file.getParent()+File.separator+newFileName));
//			System.out.println("將"+file.getName()+"文件, 重命名爲:"+newFileName);
//			System.out.println("新文件路徑:"+file.getParent()+File.separator+newFileName);
		}catch(Exception e){
			return false;
		}
		return true;
	}
	
	
}



然後 直接調用  進行上傳

FTPUtils ftpUtils = new FTPUtils();
		
	//獲取被掃描文件夾下所有符合上傳條件的文件路徑
    	String[] filePath = ftpUtils.getFilePath(null);
    	
    	for (String string : filePath) {
		File editfilename = new File(string);
		try {
			ftpUtils.upload("sql", new String[]{string});	
			System.out.println(editfilename.getName()+"上傳完成!");
		} catch (Exception e) {
			System.out.println(editfilename.getName()+"上傳失敗! 原因:["+e.getMessage()+"]");
			e.printStackTrace();
		}

			if(ftpUtils.editFileName(string, editfilename.getName().split("\\.")[0]+"_1"+".sql")){
				System.out.println("完成修改文件名!");
			}
	}


其中  ftpUtils.getFilePath(null);   這個方法是獲取某個文件夾下的所有.sql文件路徑+名稱的,傳入空值,表示使用配置的路徑。獲取到的文件名稱類似爲,xxx_20170224170400.sql,如果想要上傳其他的文件,只要改動這個方法即可。



配置文件爲  App.properties
#需要上傳文件的上級文件夾
scanpath=C\:/Users/admin/Desktop/ss/
#ftp服務器地址
address=http\://192.168.1.42:21
#用戶名
username=root
#密碼
password=123456








發佈了48 篇原創文章 · 獲贊 74 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章