Java實現FTP跨伺服器檔案操作

hlkq發表於2020-11-14

在過去的幾年工作中,曾經多次需要把檔案上傳到單獨的伺服器,而程式是在單獨的伺服器上部署的,在進行檔案操作的時候就需要跨伺服器進行操作包括:檔案上傳、檔案下載、檔案刪除等。跨伺服器檔案操作一般是需要FTP協議和SFTP協議兩種,現在就通過Java實現FTP協議的檔案上傳。要實現FTP操作檔案需要引入jar包: commons-net-1.4.1.jar
具體程式碼如下:

import java.io.*;
import java.net.MalformedURLException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

/**
*  ftp 檔案上傳工具類
* 	所需jar包(commons-net-1.4.1.jar)  
*/
public class FtpUtils {
	//ftp伺服器地址
	public String hostname ;
	//ftp伺服器埠號預設為21
	public Integer port ;
	//ftp登入賬號
	public String username ;
	//ftp登入密碼
	public String password ;
	//FTP客戶端物件
	public FTPClient ftpClient = null;
	
	//構造方法
	public FtpUtils(String hostname,Integer port,String username,String password){
		this.hostname = hostname;
		this.port = port;
		this.username = username;
		this.password = password;
	}
	
	
	/**
	 * 	初始化ftp伺服器
	 */
	public void initFtpClient() {
		ftpClient = new FTPClient();
		ftpClient.setControlEncoding("utf-8");
		try {
			System.out.println("connecting...ftp伺服器:"+this.hostname+":"+this.port); 
			ftpClient.connect(hostname, port); //連線ftp伺服器
			ftpClient.login(username, password); //登入ftp伺服器
			int replyCode = ftpClient.getReplyCode(); //是否成功登入伺服器
			if(!FTPReply.isPositiveCompletion(replyCode)){
				System.out.println("connect failed...ftp伺服器:"+this.hostname+":"+this.port); 
			}
			System.out.println("connect successfu...ftp伺服器:"+this.hostname+":"+this.port); 
		}catch (MalformedURLException e) { 
		   e.printStackTrace(); 
		}catch (IOException e) { 
		   e.printStackTrace(); 
		} 
	}

	
	/**
	* 上傳檔案
	* @param pathname ftp服務儲存地址
	* @param fileName 上傳到ftp的檔名
	* @param originfilename 待上傳檔案的名稱(絕對地址) * 
	* @return
	*/
	public boolean uploadFile( String pathname, String fileName,String originfilename){
		boolean flag = false;
		InputStream inputStream = null;
		try{
			System.out.println("開始上傳檔案");
			inputStream = new FileInputStream(new File(originfilename));
			initFtpClient();
			ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
			CreateDirecroty(pathname);
			ftpClient.makeDirectory(pathname);
			ftpClient.changeWorkingDirectory(pathname);
			ftpClient.enterLocalPassiveMode();
			flag =ftpClient.storeFile(fileName, inputStream);
			inputStream.close();
			ftpClient.logout();
			System.out.println("上傳檔案成功");
		}catch (Exception e) {
			System.out.println("上傳檔案失敗");
			e.printStackTrace();
		}finally{
			if(ftpClient.isConnected()){ 
				try{
					ftpClient.disconnect();
				}catch(IOException e){
					e.printStackTrace();
				}
			} 
			if(null != inputStream){
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				} 
			} 
		}
		return flag;
	}
	
	
	/**
	 * 上傳檔案
	 * @param pathname ftp服務儲存地址
	 * @param fileName 上傳到ftp的檔名
	 *  @param inputStream 待上傳檔案輸入流 * 
	 * @return
	 */
	public boolean uploadFileByInputStream( String pathname, String fileName,InputStream inputStream){
		boolean flag = false;
		try{
			System.out.println("開始上傳檔案");
			initFtpClient();
			ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
			CreateDirecroty(pathname);
			ftpClient.makeDirectory(pathname);
			ftpClient.changeWorkingDirectory(pathname);
			ftpClient.enterLocalPassiveMode();
			flag =ftpClient.storeFile(fileName, inputStream);
			inputStream.close();
			ftpClient.logout();
			System.out.println("上傳檔案成功");
		}catch (Exception e) {
			System.out.println("上傳檔案失敗");
			e.printStackTrace();
		}finally{
			if(ftpClient.isConnected()){ 
				try{
					ftpClient.disconnect();
				}catch(IOException e){
					e.printStackTrace();
				}
			} 
			if(null != inputStream){
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				} 
			} 
		}
		return true;
	}
	
	
	/**
	 * 上傳檔案
	 * @param pathname ftp服務儲存地址
	 * @param fileName 上傳到ftp的檔名
	 * @param inputStream 輸入檔案流 
	 * @return
	 */
	public boolean uploadFile( String pathname, String fileName,InputStream inputStream){
		boolean flag = false;
		try{
			System.out.println("開始上傳檔案");
			initFtpClient();
			ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
			CreateDirecroty(pathname);
			ftpClient.makeDirectory(pathname);
			ftpClient.changeWorkingDirectory(pathname);
			ftpClient.enterLocalPassiveMode();
			flag = ftpClient.storeFile(fileName, inputStream);
			inputStream.close();
			ftpClient.logout();
			System.out.println("上傳檔案成功");
		}catch (Exception e) {
			System.out.println("上傳檔案失敗");
			e.printStackTrace();
		}finally{
			if(ftpClient.isConnected()){ 
				try{
					ftpClient.disconnect();
				}catch(IOException e){
					e.printStackTrace();
				}
			} 
			if(null != inputStream){
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				} 
			} 
		}
		return true;
	}
	
	/**
	 * 改變目錄路徑
	 * @param directory
	 * @return
	 */
	 public boolean changeWorkingDirectory(String directory) {
		boolean flag = true;
		try {
			flag = ftpClient.changeWorkingDirectory(directory);
			if (flag) {
			  System.out.println("進入資料夾" + directory + " 成功!");

			} else {
				System.out.println("進入資料夾" + directory + " 失敗!開始建立資料夾");
			}
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
		return flag;
	 }

	/**
	 * 建立多層目錄檔案,如果有ftp伺服器已存在該檔案,則不建立,如果無,則建立
	 * @param remote
	 * @return
	 * @throws IOException
	 */
	public boolean CreateDirecroty(String remote) throws IOException {
		boolean success = true;
		String directory = remote + "/";
		// 如果遠端目錄不存在,則遞迴建立遠端伺服器目錄
		if (!directory.equalsIgnoreCase("/") && !changeWorkingDirectory(new String(directory))) {
			int start = 0;
			int end = 0;
			if (directory.startsWith("/")) {
				start = 1;
			} else {
				start = 0;
			}
			end = directory.indexOf("/", start);
			String path = "";
			String paths = "";
			while (true) {
				String subDirectory = new String(remote.substring(start, end).getBytes("GBK"), "iso-8859-1");
				path = path + "/" + subDirectory;
				if (!existFile(path)) {
					if (makeDirectory(subDirectory)) {
						changeWorkingDirectory(subDirectory);
					} else {
						changeWorkingDirectory(subDirectory);
					}
				} else {
					changeWorkingDirectory(subDirectory);
				}

				paths = paths + "/" + subDirectory;
				start = end + 1;
				end = directory.indexOf("/", start);
				// 檢查所有目錄是否建立完畢
				if (end <= start) {
					break;
				}
			}
		}
		return success;
	}

   /**
		  * 判斷ftp伺服器檔案是否存在   
	* @param path
	* @return
	* @throws IOException
	*/
	public boolean existFile(String path) throws IOException {
		boolean flag = false;
		FTPFile[] ftpFileArr = ftpClient.listFiles(path);
		if (ftpFileArr.length > 0) {
			flag = true;
		}
		return flag;
	}
	
	
	/**
	 *	 建立目錄
	 * @param dir
	 * @return
	 */
	public boolean makeDirectory(String dir) {
		boolean flag = true;
		try {
			flag = ftpClient.makeDirectory(dir);
			if (flag) {
				System.out.println("建立資料夾" + dir + " 成功!");

			} else {
				System.out.println("建立資料夾" + dir + " 失敗!");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flag;
	}
	
	/** * 下載檔案 * 
	* @param pathname FTP伺服器檔案目錄 * 
	* @param filename 檔名稱 * 
	* @param localpath 下載後的檔案路徑 * 
	* @return */
	public  boolean downloadFile(String pathname, String filename, String localpath){ 
		boolean flag = false; 
		OutputStream os=null;
		try { 
			System.out.println("開始下載檔案");
			initFtpClient();
			ftpClient.enterLocalPassiveMode();
			//切換FTP目錄 
			ftpClient.changeWorkingDirectory(pathname); 
			FTPFile[] ftpFiles = ftpClient.listFiles(); 
			for(FTPFile file : ftpFiles){ 
				if(filename.equalsIgnoreCase(file.getName())){ 
					File localFile = new File(localpath + "/" + file.getName()); 
					os = new FileOutputStream(localFile);
					flag = ftpClient.retrieveFile(file.getName(), os);
					os.close(); 
				} 
			} 
			ftpClient.logout(); 
			System.out.println("下載檔案成功");
		} catch (Exception e) { 
			System.out.println("下載檔案失敗");
			e.printStackTrace(); 
		} finally{ 
			if(ftpClient.isConnected()){ 
				try{
					ftpClient.disconnect();
				}catch(IOException e){
					e.printStackTrace();
				}
			} 
			if(null != os){
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				} 
			} 
		} 
		return flag; 
	}
	
	/** * 下載檔案 * 
	 * @param pathname FTP伺服器檔案目錄 * 
	 * @param filename 檔名稱 * 
	 * @param localpath 下載後的檔案路徑 * 
	 * @return */
	public  boolean downloadFile(String pathname, String filename,String dbFilename, String localpath){ 
		boolean flag = false; 
		OutputStream os=null;
		try { 
			System.out.println("開始下載檔案");
			initFtpClient();
			//切換FTP目錄 
			ftpClient.changeWorkingDirectory(pathname);
			ftpClient.enterLocalPassiveMode();
			FTPFile[] ftpFiles = ftpClient.listFiles(); 
			for(FTPFile file : ftpFiles){ 
				if(filename.equalsIgnoreCase(file.getName())){ 
					File localFile = new File(localpath + "/" + dbFilename); 
					os = new FileOutputStream(localFile);
					flag = ftpClient.retrieveFile(file.getName(), os);
					os.close(); 
				} 
			} 
			ftpClient.logout(); 
			flag = true; 
			System.out.println("下載檔案成功");
		} catch (Exception e) { 
			System.out.println("下載檔案失敗");
			e.printStackTrace(); 
		} finally{ 
			if(ftpClient.isConnected()){ 
				try{
					ftpClient.disconnect();
				}catch(IOException e){
					e.printStackTrace();
				}
			} 
			if(null != os){
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				} 
			} 
		} 
		return flag; 
	}
	
	/** * 獲取ftp檔案輸入流 * 
	 * @param pathname FTP伺服器檔案目錄 * 
	 * @param filename 檔名稱 * 
	 * @return */
	public  InputStream downloadFile(String pathname, String filename){ 
		InputStream fileStream = null;
		try { 
			initFtpClient();
			//切換FTP目錄 
			ftpClient.changeWorkingDirectory(pathname); 
			FTPFile[] ftpFiles = ftpClient.listFiles(); 
			for(FTPFile file : ftpFiles){ 
				if(filename.equalsIgnoreCase(file.getName())){
					ftpClient.enterLocalPassiveMode();
					fileStream = ftpClient.retrieveFileStream(new String(file.getName().getBytes("GBK"),"ISO8859-1"));
					break;
				} 
			} 
			ftpClient.logout(); 
		} catch (Exception e) { 
			System.out.println("獲取下載的檔案流");
			e.printStackTrace(); 
		} finally{ 
			if(ftpClient.isConnected()){ 
				try{
					ftpClient.disconnect();
				}catch(IOException e){
					e.printStackTrace();
				}
			} 
		} 
		return fileStream; 
	}
	
	/** * 刪除檔案 * 
	* @param pathname FTP伺服器儲存目錄 * 
	* @param filename 要刪除的檔名稱 * 
	* @return */ 
	public boolean deleteFile(String pathname, String filename){ 
		boolean flag = false; 
		try { 
			System.out.println("開始刪除檔案");
			initFtpClient();
			//切換FTP目錄 
			ftpClient.changeWorkingDirectory(pathname);
			ftpClient.enterLocalPassiveMode();
			ftpClient.dele(filename);
			ftpClient.logout();
			flag = true; 
			System.out.println("刪除檔案成功");
		} catch (Exception e) { 
			System.out.println("刪除檔案失敗");
			e.printStackTrace(); 
		} finally {
			if(ftpClient.isConnected()){ 
				try{
					ftpClient.disconnect();
				}catch(IOException e){
					e.printStackTrace();
				}
			} 
		}
		return flag; 
	}
	
	
	/**
	 * 測試
	 * @param args
	 */
	public static void main(String[] args) {
		FtpUtils ftp =new FtpUtils("192.168.1.123",21,"aaa","aa123");
		//ftp.downloadFile("ftpFile/ss/model", "ceshi.xlsx","E:/abc");
		//ftp.deleteFile("ftpFile/ss/model","ceshi.txt");

		/*InputStream inputStream = null;
		try {
			inputStream = new FileInputStream(new File("E:/abc/abc.txt"));
			ftp.uploadFileByInputStream("ftpFile/ss/model",  "abc.txt", inputStream);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}*/

		boolean flag = ftp.uploadFile( "/", "bbb.txt","E:/abc/bbb.txt");
		System.out.println(flag);
		
		/*InputStream downloadFile = ftp.downloadFile("/home/aaa/ftpFile/data/policy/model", "Report1.doc");
		System.out.println(downloadFile);
		FtpUtils _ftp =new FtpUtils("192.168.1.123",21,"aaa","aa123");

		_ftp.uploadFile("ftpFile/data/model","Report1.doc", downloadFile);*/
		//ftp.downloadFile("ftpFile/data/policy/model", "Report1.doc","2e0ee9b1476c4bd3bb0cad5ecef6d4c3.pdf", "D:/test/uploadfile/modelfile/");
		//ftp.deleteFile("ftpFile/data", "123.docx");
		System.out.println("ok");
		
	}
}

相關文章