天天看點

java實作FTP和 SFTP連接配接遠端伺服器下載下傳檔案java實作FTP和 SFTP連接配接遠端伺服器下載下傳檔案前言一、FTP是什麼?如何實作。二、SFTP是什麼?如何實作。總結

java實作FTP和 SFTP連接配接遠端伺服器下載下傳檔案

文章目錄

  • java實作FTP和 SFTP連接配接遠端伺服器下載下傳檔案
  • 前言
  • 一、FTP是什麼?如何實作。
    • 1.實作代碼
  • 二、SFTP是什麼?如何實作。
    • 1.代碼實作
  • 總結

前言

為什魔寫這片文章呢,因為關于ftp和sftp的文章介紹的太少啦 。

提示:以下是本篇文章正文内容,下面案例可供參考

一、FTP是什麼?如何實作。

來自百度百科 :檔案傳輸協定(File Transfer Protocol,FTP)是用于在網絡上進行檔案傳輸的一套标準協定,它工作在 OSI 模型的第七層, TCP 模型的第四層, 即應用層, 使用 TCP 傳輸而不是 UDP, 客戶在和伺服器建立連接配接前要經過一個“三次握手”的過程, 保證客戶與伺服器之間的連接配接是可靠的, 而且是面向連接配接, 為資料傳輸提供可靠保證。

FTP允許使用者以檔案操作的方式(如檔案的增、删、改、查、傳送等)與另一主機互相通信。然而, 使用者并不真正登入到自己想要存取的計算機上面而成為完全使用者, 可用FTP程式通路遠端資源, 實作使用者往返傳輸檔案、目錄管理以及通路電子郵件等等, 即使雙方計算機可能配有不同的作業系統和檔案存儲方式。

1.實作代碼

public class FtpTools {
	public static Logger logger = SnowLog.getLogger(FtpTools.class);
	private static String ftpHost; 										// IP
	private static int ftpPort; 										// port
	private static String ftpUserName; 									// 使用者
	private static String ftpPassword; 									// 密碼
	private static FTPClient ftpClient; 								// IP
	/**
	 * 初始化ftp資訊
	 * @param type
	 * @throws Exception
	 */
	public void init(String type) throws Exception {
		logger.info("***********************初始化FTP資訊***********************");
		String hostMagicId = null;
		String userNameMagicId = null;
		String passWordMagicId = null;
		String cbsPortMagicId=null;
		if(InterConstants.FTP_CBS_01.equals(type)){
			hostMagicId = "CBS_HOST";
			userNameMagicId = "CBS_USERNAME";
			passWordMagicId = "CBS_PASSWORD";
			cbsPortMagicId="CBS_PORT";
		}else{
			SnowExceptionUtil.throwErrorException("ftp類型非法,初始化ftp資訊失敗");
		}
		TblSysParam selectHost = DBDaos.newInstance().select(TblSysParam.class, "FTP", hostMagicId);
		if (selectHost == null) {
			SnowExceptionUtil.throwErrorException("請配置FTP位址!");
		}
		ftpHost = selectHost.getParamValueTx();
		TblSysParam selectPort = DBDaos.newInstance().select(TblSysParam.class, "FTP", cbsPortMagicId);
		if (selectPort == null) {
			SnowExceptionUtil.throwErrorException("請配置FTP端口!");
		}
		ftpPort = Integer.parseInt(selectPort.getParamValueTx());
		TblSysParam selectUsername = DBDaos.newInstance().select(TblSysParam.class, "FTP", userNameMagicId);
		if (selectUsername == null) {
			SnowExceptionUtil.throwErrorException("請配置FTP使用者名!");
		}
		ftpUserName = selectUsername.getParamValueTx();
		TblSysParam selectPassword = DBDaos.newInstance().select(TblSysParam.class, "FTP", passWordMagicId);
		if (selectPassword == null) {
			SnowExceptionUtil.throwErrorException("請配置FTP密碼!");
		}
		ftpPassword = selectPassword.getParamValueTx();

	}

	/**
	 * 連接配接ftp服務
	 * @throws Exception
	 */
	public  void connectClient() throws Exception {
		logger.info("***********************登入FTP***********************");
		ftpClient = new FTPClient();
		try {
			ftpClient = new FTPClient();
			ftpClient.connect(ftpHost, ftpPort);// 連接配接FTP伺服器
			ftpClient.login(ftpUserName, ftpPassword);// 登陸FTP伺服器
			//設定編碼
			ftpClient.setControlEncoding("GBK");
			ftpClient.setBufferSize(8096);
			if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
				logger.info("未連接配接到FTP,使用者名或密碼錯誤。");
				ftpClient.disconnect();
			} else {
				logger.info("FTP連接配接成功。");
			}
		} catch (SocketException e) {
			logger.error("FTP的IP位址可能錯誤,請正确配置。message={}",e);
			SnowExceptionUtil.throwErrorException("FTP伺服器連接配接失敗");
		} catch (IOException e) {
			logger.error("FTP的端口錯誤,請正确配置。message={}",e);
			SnowExceptionUtil.throwErrorException("FTP伺服器連接配接失敗");
		}catch (Exception e) {
			logger.error("FTP連接配接失敗。message={}",e);
			SnowExceptionUtil.throwErrorException("FTP伺服器連接配接失敗");
		}
	}

	/**
	 *  檢驗指定路徑的檔案是否存在ftp伺服器中
	 * @param filePath--指定絕對路徑的檔案
	 * @return
	 */
	public  boolean isFTPFileExist(String filePath){
		// 判斷檔案是否存在
		Boolean isexist = false;
		try {
			// 提取絕對位址的目錄以及檔案名
			filePath = filePath.replace("ftp://"+ftpHost+":"+ftpPort+"/", "");
			String dir = filePath.substring(0, filePath.lastIndexOf("/"));
			String file = filePath.substring(filePath.lastIndexOf("/")+1);

			// 進入檔案所在目錄,注意編碼格式,以能夠正确識别中文目錄
			ftpClient.changeWorkingDirectory(new String(dir.getBytes("GBK"),FTP.DEFAULT_CONTROL_ENCODING));

			// 檢驗檔案是否存在
			InputStream is = ftpClient.retrieveFileStream(new String(file.getBytes("GBK"),FTP.DEFAULT_CONTROL_ENCODING));
			if(is == null || ftpClient.getReplyCode() == FTPReply.FILE_UNAVAILABLE){
				return isexist;
			}

			if(is != null){
				isexist = true;
				is.close();
				ftpClient.completePendingCommand();
			}
			return isexist;
		} catch (Exception e) {
			logger.error("檢驗ftp指定路徑的檔案是否存在失敗,message={}",e);
		}
		return isexist;
	}
	/**
	 * ftp服務檔案下載下傳到指定目錄
	 * @param ftpPath FTP伺服器中檔案所在路徑
	 * @param localPath 下載下傳到本地的位置
	 * @param fileName 檔案名稱
	 */
	public  void downloadFtpFile(String ftpPath, String localPath,String fileName) throws Exception {
		//判斷檔案夾是否存在, 不存在建立
		makeDirs(localPath);
		ftpClient.setControlEncoding("GBK"); // 中文支援
		ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
		ftpClient.enterLocalPassiveMode();
		ftpClient.changeWorkingDirectory(StringUtils.trim(ftpPath));
		File file = new File(localPath+"/"+fileName);
		OutputStream os = new FileOutputStream(file);
		ftpClient.retrieveFile(new String(file.getName().getBytes(), "ISO-8859-1"), os);
		os.close();
	}

	/**
	 * 關閉FTP伺服器
	 */
	public  void closeServer() {
		try {
			if (ftpClient != null) {
				ftpClient.logout();
				ftpClient.disconnect();
			}
		} catch (IOException e) {
			logger.error("ftpl連接配接關閉失敗,message={}",e);
		}

	}

	/**
	 * 判斷本地路徑是否存在,不存在就建立路徑
	 */
	public  void makeDirs(String localSavePath) {
		File localFile = new File(localSavePath);
		if (!localFile.exists()) {
			localFile.mkdirs();
		}
	}
}

           

下載下傳到本地,結果:

java實作FTP和 SFTP連接配接遠端伺服器下載下傳檔案java實作FTP和 SFTP連接配接遠端伺服器下載下傳檔案前言一、FTP是什麼?如何實作。二、SFTP是什麼?如何實作。總結

二、SFTP是什麼?如何實作。

sftp是Secure File Transfer Protocol的縮寫,安全檔案傳送協定。可以為傳輸檔案提供一種安全的網絡的加密方法。sftp 與 ftp 有着幾乎一樣的文法和功能。SFTP 為 SSH的其中一部分,是一種傳輸檔案至 Blogger 伺服器的安全方式。其實在SSH軟體包中,已經包含了一個叫作SFTP(Secure File Transfer Protocol)的安全檔案資訊傳輸子系統,SFTP本身沒有單獨的守護程序,它必須使用sshd守護程序(端口号預設是22)來完成相應的連接配接和答複操作,是以從某種意義上來說,SFTP并不像一個伺服器程式,而更像是一個用戶端程式。SFTP同樣是使用加密傳輸認證資訊和傳輸的資料,是以,使用SFTP是非常安全的。但是,由于這種傳輸方式使用了加密/解密技術,是以傳輸效率比普通的FTP要低得多,如果您對網絡安全性要求更高時,可以使用SFTP代替FTP。(來自百度百科)

1.代碼實作

注意:重要的事情說三遍 :::初始化ftp資訊,init()方法段邏輯你可以略過,自己去配置連接配接的參數資訊

* 目前我們采用将Sftp連接配接參數,存在資料庫裡面了,是以寫了一個查詢配置資訊的方法。

/**
 * SFTP上傳下載下傳檔案
 */
public class SftpUtils {
	private final Logger logger = LoggerFactory.getLogger(SftpUtils.class);// SnowLog.getLogger(this.getClass());
	private static String ftpHost; 										// IP
	private static int ftpPort; 										// port
	private static String ftpUserName; 									// 使用者
	private static String ftpPassword; 									// 密碼


	/**
	 * 連接配接sftp伺服器
	 * @param host 主機
	 * @param port 端口
	 * @param username 使用者名
	 * @param password 密碼
	 * @return
	 */
	public ChannelSftp connect(String host, int port, String username, String password) {
		ChannelSftp sftp = null;
		Channel channel=null;
		Session sshSession=null;
		try {
			JSch jsch = new JSch();
			jsch.getSession(username, host, port);
			sshSession = jsch.getSession(username, host, port);
			if(logger.isInfoEnabled()){
				logger.info("***************** Session created. **********************");
				logger.info("***************** stf host is "+host+"port is "+port+"  username is "+username+"  password is  "+password+"**********************");
			}
			sshSession.setPassword(password);
			Properties sshConfig = new Properties();
			sshConfig.put("StrictHostKeyChecking", "no");
			sshSession.setConfig(sshConfig);
			sshSession.connect();
			if(logger.isInfoEnabled()){
				logger.info("***************** Session connected. **********************");
				logger.info("***************** Opening Channel. **********************");
			}
			channel = sshSession.openChannel("sftp");
			channel.connect();
			sftp = (ChannelSftp) channel;
			if(logger.isInfoEnabled()){
				logger.info("***************** Connected to " + host + ". **********************");
			}
		} catch (Throwable e) {
			if (channel!=null) {
				try {
					channel.disconnect();
				}catch(Throwable e1) {
				}
			}
			
			if (sshSession!=null) {
				try {
					sshSession.disconnect();
				}catch(Throwable e1) {
				}
			}
			
			logger.error(e.getMessage(), e);
		}
		return sftp;
	}
	
	/**
	 * 關閉連接配接
	 * @param sftp
	 */
	public void disconnect(String host, ChannelSftp sftp){
		// 關閉連接配接
		try {
			if (null != sftp) {
				sftp.disconnect();
				if(logger.isInfoEnabled()){
					logger.info("***************** Closing Channel. **********************");
				}
				if (null != sftp.getSession()) {
					sftp.getSession().disconnect();
					if(logger.isInfoEnabled()){
						logger.info("***************** Session disconnect. **********************");
					}
				}
			}
			if (logger.isInfoEnabled()) {
				logger.info("**************** Disconnect to " + host + ". *******************");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 判斷目錄下是否存在檔案或者檔案夾
	 * @param directory
	 * @param fileName
	 * @param sftp
	 * @return
	 */
	public boolean isExist(String directory, String fileName, ChannelSftp sftp) {
		try {
			Vector<LsEntry> v = listFiles(directory, sftp);
			Iterator<LsEntry> it = v.iterator();
			while (it.hasNext()) {
				LsEntry entry = it.next();
				String flName = entry.getFilename();
				if (flName.equals(fileName)) {
					return true;
				}
			}
		} catch (SftpException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 上傳檔案
	 * @param directory 上傳的目錄
	 * @param uploadFile 要上傳的檔案
	 * @param sftp
	 */
	public String upload(String directory, String uploadFile, ChannelSftp sftp) {
		String successFlg = "0";
		try {
			sftp.cd(directory);
			File file = new File(uploadFile);
			sftp.put(new FileInputStream(file), file.getName());
			if(logger.isInfoEnabled()){
				logger.info("***************** Finished **********************");
			}
		} catch (Exception e) {
			successFlg = "1";
			e.printStackTrace();
		}
		return successFlg;
	}

	/**
	 * 下載下傳檔案
	 * @param directory 下載下傳目錄
	 * @param downloadFile 下載下傳的檔案
	 * @param saveFile 存在本地的路徑
	 * @param sftp
	 */
	public String download(String directory, String downloadFile, String saveFile, ChannelSftp sftp) {
		String successFlg = "0";
		try {
			sftp.cd(directory);
			File file = new File(saveFile);
			if(!file.getParentFile().exists()){
				file.getParentFile().mkdirs();
			}
			sftp.get(downloadFile, new FileOutputStream(file));
			if(logger.isInfoEnabled()){
				logger.info("***************** Finished **********************");
			}
		} catch (Exception e) {
			successFlg = "1";
			e.printStackTrace();
		}
		return successFlg;
	}

	/**
	 * 删除檔案
	 * @param directory 要删除檔案所在目錄
	 * @param deleteFile 要删除的檔案
	 * @param sftp
	 */
	public void delete(String directory, String deleteFile, ChannelSftp sftp) {
		try {
			sftp.cd(directory);
			sftp.rm(deleteFile);
			if(logger.isInfoEnabled()){
				logger.info("***************** Finished **********************");
			}
			if (null != sftp) {
				sftp.disconnect();
				if (null != sftp.getSession()) {
					sftp.getSession().disconnect();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 列出目錄下的檔案
	 * @param directory  要列出的目錄
	 * @param sftp
	 * @return
	 * @throws SftpException
	 */
	@SuppressWarnings("unchecked")
	public Vector<LsEntry> listFiles(String directory, ChannelSftp sftp) throws SftpException {
		return sftp.ls(directory);
	}

	/**
	 * 初始化ftp資訊,init()方法段邏輯你可以略過,自己去配置連接配接的參數資訊
	 * 目前我們采用将Sftp連接配接參數,存在資料庫裡面了,是以寫了一個查詢配置資訊的方法。
	 * @param type
	 * @throws Exception
	 */
	public Map<String,String> init(String type) throws Exception {
		logger.info("***********************初始化SFTP資訊***********************");
		String hostMagicId = "CBS_HOST";
		String userNameMagicId = "CBS_USERNAME";
		String passWordMagicId = "CBS_PASSWORD";
		String cbsPortMagicId="CBS_PORT";
		Map<String, String> hashMap = new HashMap<>();
		TblSysParam selectHost = DBDaos.newInstance().select(TblSysParam.class, "FTP", hostMagicId);
		if (selectHost == null) {
			SnowExceptionUtil.throwErrorException("請配置FTP位址!");
		}
		ftpHost = selectHost.getParamValueTx();
		hashMap.put(hostMagicId,ftpHost);
		TblSysParam selectPort = DBDaos.newInstance().select(TblSysParam.class, "FTP", cbsPortMagicId);
		if (selectPort == null) {
			SnowExceptionUtil.throwErrorException("請配置FTP端口!");
		}
		ftpPort = Integer.parseInt(selectPort.getParamValueTx());
		hashMap.put(cbsPortMagicId, String.valueOf(ftpPort));

		TblSysParam selectUsername = DBDaos.newInstance().select(TblSysParam.class, "FTP", userNameMagicId);
		if (selectUsername == null) {
			SnowExceptionUtil.throwErrorException("請配置FTP使用者名!");
		}
		ftpUserName = selectUsername.getParamValueTx();
		hashMap.put(userNameMagicId,ftpUserName);

		TblSysParam selectPassword = DBDaos.newInstance().select(TblSysParam.class, "FTP", passWordMagicId);
		if (selectPassword == null) {
			SnowExceptionUtil.throwErrorException("請配置FTP密碼!");
		}
		ftpPassword = selectPassword.getParamValueTx();
		hashMap.put(passWordMagicId,ftpPassword);
        return hashMap;
	}

	/**
	 * 判斷本地路徑是否存在,不存在就建立路徑
	 */
	public  void makeDirs(String localSavePath) {
		File localFile = new File(localSavePath);
		if (!localFile.exists()) {
			localFile.mkdirs();
		}
	}
}
           

下載下傳檔案結果圖

java實作FTP和 SFTP連接配接遠端伺服器下載下傳檔案java實作FTP和 SFTP連接配接遠端伺服器下載下傳檔案前言一、FTP是什麼?如何實作。二、SFTP是什麼?如何實作。總結

總結

Ftp和Sftp的主要差別就是通信協定不同,Ftp使用的是Tcp協定Sftp使用的是ssh2協定,本身傳輸的方式是不同的,安全性:Sftp使用加密傳輸認證資訊和傳輸的資料,是以使用Sftp相對于Ftp是非常安全。

效率:Sftp這種傳輸方式使用了加密解密技術,是以傳輸效率比普通的Ftp要低得多——————至此敬我們相關核心系統的朋友們,是他們逼得我學會個很多yyds。