1. 程式人生 > >java實現ftp檔案操作的方式有哪些?

java實現ftp檔案操作的方式有哪些?

由於時間問題,這裡嘗試了兩種方式:Apache組織提供的org.apache.commons.net.ftp、edtFTPj

一、org.apache.commons.net.ftp

要使用org.apache.commons.net.ftp實現功能需要專案內引入commons-net-1.4.1.jar、jakarta-oro-2.0.8.jar(不引入此包, FTPClient.listFiles()會報錯,具體原因沒有細究,當然希望高手給予補充)。

1、可以留意一下checkDirectory方法,因為之前做的時候想做一個校驗:“java判斷指定資料夾是否存在,如果不存在就自動建立”。然後在網上找了以下三種方案:

①ftpClient.makeDirectory(目錄地址); 返回結果true或false
②ftpClient.cd(dir);  通過異常控制,報異常則為無。
③用changeWorkingDirectory,返回 false 沒有 true 是有 。

個人感覺上述方法都不靠譜,所以採用了遍歷資料夾的方式進行驗證,當然如果你ftp伺服器上的目錄太多,用這個方法最好慎重一下。

2、中文亂碼解決採用的是:http://www.linuxidc.com/Linux/2014-10/107585.htm給出的解決方案。

package com.cf.mytest.ftp;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

public class ApacheFtp {

	
	/** 本地字元編碼 */
	private static String LOCAL_CHARSET = "GBK";
	
	// FTP協議裡面,規定檔名編碼為iso-8859-1
	private static String SERVER_CHARSET = "ISO-8859-1";

	//檢查ftp目錄
	public static boolean checkDirectory(FTPClient ftp, String dirName) {
		boolean _flag = false;
		try {
	        FTPFile[] files = ftp.listFiles();
			for (int i = 0; i < files.length; i++) {
				FTPFile file = files[i];
				if (file.isDirectory()) {
					if (dirName.equalsIgnoreCase(file.getName())) {
						_flag = true;
						break;
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return _flag;
	}
	
	


	/** 
	 * Description: 向FTP伺服器上傳檔案 
	 * @param url FTP伺服器hostname 
	 * @param port FTP伺服器埠 
	 * @param username FTP登入賬號 
	 * @param password FTP登入密碼 
	 * @param path FTP伺服器儲存目錄 
	 * @param filename 上傳到FTP伺服器上的檔名 
	 * @param input 輸入流 
	 * @return 成功返回true,否則返回false 
	 */  
	public static int uploadFile(String path, String filename, InputStream input) {  
	    int success = 0;  
	    //ftp連線引數
		String ftpServer = "192.168.1.254";
		int ftpPort = 21;
		String ftpUser = "lmss";
		String ftpPassword = "test123";
	    FTPClient ftp = new FTPClient();  
	    try {
	        int reply;
	        // 連線FTP伺服器 
	        ftp.connect(ftpServer, ftpPort); 
	        // 登入ftp
	        ftp.login(ftpUser, ftpPassword);
	        // 看返回的值是不是230,如果是,表示登陸成功
	        reply = ftp.getReplyCode(); 
	        // 以2開頭的返回值就會為真 
	        if (!FTPReply.isPositiveCompletion(reply)) {
	            ftp.disconnect();
	            return success;
	        }
	        // 檢查路徑目錄,沒有就建立
	        path = StringUtils.removeStart(path, "/");
    		String[] typeArray = path.split("/");
    		for (int i = 0; i < typeArray.length; i++) {
    			if (!checkDirectory(ftp, typeArray[i])){
    				ftp.makeDirectory(typeArray[i]);
    			}
    			ftp.changeWorkingDirectory(typeArray[i]);
    		}
	        // 轉到指定上傳目錄  
//	        ftp.changeWorkingDirectory(path);
    		//設定每次讀取檔案流時快取陣列的大小
			ftp.setBufferSize(1024); 
			//設定編碼格式,解決中文亂碼問題
			if (FTPReply.isPositiveCompletion(ftp.sendCommand("OPTS UTF8", "ON"))) {// 開啟伺服器對UTF-8的支援,如果伺服器支援就用UTF-8編碼,否則就使用本地編碼(GBK).
    			LOCAL_CHARSET = "UTF-8";
    		}
    		ftp.setControlEncoding(LOCAL_CHARSET);
	        // 設定檔案型別(二進位制) 
			ftp.setFileType(FTPClient.BINARY_FILE_TYPE); 
	        // 將上傳檔案儲存到指定目錄
	        ftp.storeFile(new String(filename.getBytes(LOCAL_CHARSET), SERVER_CHARSET), input);  
	        // 退出ftp 
	        ftp.logout();
	        success = 1;
	    } catch (IOException e) {
	        e.printStackTrace();  
	    } finally {
	    	try{
	    		if(input != null){
	    			input.close();
	    		}
	    		if (ftp.isConnected()) {
		        	 ftp.disconnect();  
		        }
	    	}catch(Exception e){
	    		e.printStackTrace();
	    	}
	    }
	    return success;
	}
	
	
	/** 
	 * Description: 刪除ftp上的檔案
	 * @return 成功返回true,否則返回false 
	 */  
	public static boolean deleteFileFtp(String path) {
		boolean success = false;
		//ftp連線引數
		String ftpServer = "192.168.1.254";
		int ftpPort = 21;
		String ftpUser = "lmss";
		String ftpPassword = "test123";
	    FTPClient ftp = new FTPClient();  
	    try {
	    	 int reply;
	        // 連線FTP伺服器 
	        ftp.connect(ftpServer, ftpPort); 
	        // 登入ftp
	        ftp.login(ftpUser, ftpPassword);
	        // 看返回的值是不是230,如果是,表示登陸成功
	        reply = ftp.getReplyCode(); 
	        // 以2開頭的返回值就會為真 
	        if (!FTPReply.isPositiveCompletion(reply)) {
	            ftp.disconnect();
	            return success;
	        }
	        success = ftp.deleteFile(path);
	    } catch (IOException e) {
	    	e.printStackTrace();
	    } finally {  
	        if (ftp.isConnected()) {
	            try {  
	                ftp.disconnect();  
	            } catch (IOException ioe) {
	            }
	        }
	    }
	    return success;
	}
	
	
	public static void main(String[] args) throws Exception {
		File file = new File("d:\\3.png");
		FileInputStream fis = new FileInputStream(file);
		ApacheFtp.uploadFile("/resource/png","4.png",fis);
	}
	

}

二、edtFTPj

要使用edtFTPj實現功能,專案需要引入edtftpj.jar。

package com.cf.mytest.ftp;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import org.apache.commons.lang.StringUtils;

import com.enterprisedt.net.ftp.FTPFile;
import com.enterprisedt.net.ftp.FileTransferClient;
import com.enterprisedt.net.ftp.FileTransferOutputStream;

public class EdtFTPjTest {

	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		File file = new File("d:\\3.png");
		FileInputStream fis = new FileInputStream(file);
		EdtFTPjTest.writeFileToFtp("resource/png","4.png",fis);
	}
	
	// 連線到ftp,建立文字目錄,指定最後一級目錄
	public static FileTransferClient connect(String directory) {
		FileTransferClient ftp = new FileTransferClient();
		ftp.getAdvancedSettings().setControlEncoding("gb2312");
		//ftp配置資訊
		String ftpServer = "192.168.1.254";
		int ftpPort = 21;
		String ftpUser = "lmss";
		String ftpPassword = "test123";
		try {
			ftp.setRemoteHost(ftpServer);
			ftp.setRemotePort(ftpPort);
			ftp.setUserName(ftpUser);
			ftp.setPassword(ftpPassword);
			ftp.connect();
			
			/*
			 * 迴圈建立資料夾目錄
			 */
			
			//判斷路徑開始是否是/,如果是就刪除掉
			directory = StringUtils.removeStart(directory, "/");
			String[] typeArray = directory.split("/");
			for (int i = 0; i < typeArray.length; i++) {
				if (!checkDirectory(ftp, typeArray[i]))
					ftp.createDirectory(typeArray[i]);
				ftp.changeDirectory(typeArray[i]);
			}
			
		} catch (Exception e) {
			ftp = null;
			e.printStackTrace();
		}
		return ftp;
	}
	

	// 更改ftp的路徑
	public static boolean checkDirectory(FileTransferClient ftp, String dirName) {
		boolean _flag = false;
		try {
			FTPFile[] files = ftp.directoryList();
			for (int i = 0; i < files.length; i++) {
				if (files[i].isDir()) {
					if (dirName.equalsIgnoreCase(files[i].getName())) {
						_flag = true;
						break;
					}
				}
			}
		} catch (Exception e) {
		}
		return _flag;
	}
	
	
	
	/*
	 * 寫檔案到ftp
	 * param: dec:檔案所在目錄,name:檔名稱,in:輸入流
	 */
	public static int writeFileToFtp(String dec, String name, InputStream in) {
		int flag = 0;
		FileTransferClient ftp = null;
		FileTransferOutputStream output = null;
		try {
			//建立目錄,指向最後一級目錄
			ftp = connect(dec);
			//設定檔名
			output = ftp.uploadStream(name);
			byte[] buf = new byte[1024]; 
		    int hasRead=0;
		    while((hasRead=in.read(buf))>0){
		    	output.write(buf, 0, hasRead);
		    }
		    output.flush();
		    flag = 1;
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			 try{
				 if(output != null){
					 output.close();
				 }
				 if(ftp!=null && ftp.isConnected()){
					 ftp.disconnect();
				 }
			 }catch(Exception e){
				 e.printStackTrace();
			 }
		}
		return flag;
	}
	


}

以上程式碼,親測好用!

所需jar檔案如下:點選開啟連結

最後希望各位大神能夠給我指出程式碼中的缺陷,還有將來可能遇到的問題,多謝!