Java連接服務(wù)器的兩種方式SFTP和FTP
區(qū)別
FTP是一種文件傳輸協(xié)議,一般是為了方便數(shù)據(jù)共享的。包括一個(gè)FTP服務(wù)器和多個(gè)FTP客戶(hù)端。FTP客戶(hù)端通過(guò)FTP協(xié)議在服務(wù)器上下載資源。FTP客戶(hù)端通過(guò)FTP協(xié)議在服務(wù)器上下載資源。而一般要使用FTP需要在服務(wù)器上安裝FTP服務(wù)。
而SFTP協(xié)議是在FTP的基礎(chǔ)上對(duì)數(shù)據(jù)進(jìn)行加密,使得傳輸?shù)臄?shù)據(jù)相對(duì)來(lái)說(shuō)更安全,但是傳輸?shù)男时菷TP要低,傳輸速度更慢(不過(guò)現(xiàn)實(shí)使用當(dāng)中,沒(méi)有發(fā)現(xiàn)多大差別)。SFTP和SSH使用的是相同的22端口,因此免安裝直接可以使用。
總結(jié):
一;FTP要安裝,SFTP不要安裝。
二;SFTP更安全,但更安全帶來(lái)副作用就是的效率比FTP要低。
FtpUtil
<!--ftp文件上傳-->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.*;
@Component
public class FtpUtil {
private static final Logger logger = LoggerFactory.getLogger(FtpUtil.class);
//ftp服務(wù)器地址
@Value("${ftp.server}")
private String hostname;
//ftp服務(wù)器端口
@Value("${ftp.port}")
private int port;
//ftp登錄賬號(hào)
@Value("${ftp.userName}")
private String username;
//ftp登錄密碼
@Value("${ftp.userPassword}")
private String password;
/**
* 初始化FTP服務(wù)器
*
* @return
*/
public FTPClient getFtpClient() {
FTPClient ftpClient = new FTPClient();
ftpClient.setControlEncoding("UTF-8");
try {
//設(shè)置連接超時(shí)時(shí)間
ftpClient.setDataTimeout(1000 * 120);
logger.info("連接FTP服務(wù)器中:" + hostname + ":" + port);
//連接ftp服務(wù)器
ftpClient.connect(hostname, port);
//登錄ftp服務(wù)器
ftpClient.login(username, password);
// 是否成功登錄服務(wù)器
int replyCode = ftpClient.getReplyCode();
if (FTPReply.isPositiveCompletion(replyCode)) {
logger.info("連接FTP服務(wù)器成功:" + hostname + ":" + port);
} else {
logger.error("連接FTP服務(wù)器失敗:" + hostname + ":" + port);
closeFtpClient(ftpClient);
}
} catch (IOException e) {
logger.error("連接ftp服務(wù)器異常", e);
}
return ftpClient;
}
/**
* 上傳文件
*
* @param pathName 路徑
* @param fileName 文件名
* @param inputStream 輸入文件流
* @return
*/
public boolean uploadFileToFtp(String pathName, String fileName, InputStream inputStream) {
boolean isSuccess = false;
FTPClient ftpClient = getFtpClient();
try {
if (ftpClient.isConnected()) {
logger.info("開(kāi)始上傳文件到FTP,文件名稱(chēng):" + fileName);
//設(shè)置上傳文件類(lèi)型為二進(jìn)制,否則將無(wú)法打開(kāi)文件
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
//路徑切換,如果目錄不存在創(chuàng)建目錄
if (!ftpClient.changeWorkingDirectory(pathName)) {
boolean flag = this.changeAndMakeWorkingDir(ftpClient, pathName);
if (!flag) {
logger.error("路徑切換(創(chuàng)建目錄)失敗");
return false;
}
}
//設(shè)置被動(dòng)模式,文件傳輸端口設(shè)置(如上傳文件夾成功,不能上傳文件,注釋這行,否則報(bào)錯(cuò)refused:connect)
ftpClient.enterLocalPassiveMode();
ftpClient.storeFile(fileName, inputStream);
inputStream.close();
ftpClient.logout();
isSuccess = true;
logger.info(fileName + "文件上傳到FTP成功");
} else {
logger.error("FTP連接建立失敗");
}
} catch (Exception e) {
logger.error(fileName + "文件上傳異常", e);
} finally {
closeFtpClient(ftpClient);
closeStream(inputStream);
}
return isSuccess;
}
/**
* 刪除文件
*
* @param pathName 路徑
* @param fileName 文件名
* @return
*/
public boolean deleteFile(String pathName, String fileName) {
boolean flag = false;
FTPClient ftpClient = getFtpClient();
try {
logger.info("開(kāi)始刪除文件");
if (ftpClient.isConnected()) {
//路徑切換
ftpClient.changeWorkingDirectory(pathName);
ftpClient.enterLocalPassiveMode();
ftpClient.dele(fileName);
ftpClient.logout();
flag = true;
logger.info("刪除文件成功");
} else {
logger.info("刪除文件失敗");
}
} catch (Exception e) {
logger.error(fileName + "文件刪除異常", e);
} finally {
closeFtpClient(ftpClient);
}
return flag;
}
/**
* 關(guān)閉FTP連接
*
* @param ftpClient
*/
public void closeFtpClient(FTPClient ftpClient) {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
logger.error("關(guān)閉FTP連接異常", e);
}
}
}
/**
* 關(guān)閉文件流
*
* @param closeable
*/
public void closeStream(Closeable closeable) {
if (null != closeable) {
try {
closeable.close();
} catch (IOException e) {
logger.error("關(guān)閉文件流異常", e);
}
}
}
/**
* 路徑切換(沒(méi)有則創(chuàng)建)
*
* @param ftpClient FTP服務(wù)器
* @param path 路徑
*/
public void changeAndMakeWorkingDir(FTPClient ftpClient, String path) {
boolean flag = false;
try {
String[] path_array = path.split("/");
for (String s : path_array) {
boolean b = ftpClient.changeWorkingDirectory(s);
if (!b) {
ftpClient.makeDirectory(s);
ftpClient.changeWorkingDirectory(s);
}
}
flag = true;
} catch (IOException e) {
logger.error("路徑切換異常", e);
}
return flag;
}
/**
* 從FTP下載到本地文件夾
*
* @param ftpClient FTP服務(wù)器
* @param pathName 路徑
* @param targetFileName 文件名
* @param localPath 本地路徑
* @return
*/
public boolean downloadFile(FTPClient ftpClient, String pathName, String targetFileName, String localPath) {
boolean flag = false;
OutputStream os = null;
try {
System.out.println("開(kāi)始下載文件");
//切換FTP目錄
ftpClient.changeWorkingDirectory(pathName);
ftpClient.enterLocalPassiveMode();
FTPFile[] ftpFiles = ftpClient.listFiles();
for (FTPFile file : ftpFiles) {
String ftpFileName = file.getName();
if (targetFileName.equalsIgnoreCase(ftpFileName)) {
File localFile = new File(localPath + targetFileName);
os = new FileOutputStream(localFile);
ftpClient.retrieveFile(file.getName(), os);
os.close();
}
}
ftpClient.logout();
flag = true;
logger.info("下載文件成功");
} catch (Exception e) {
logger.error("下載文件失敗", e);
} finally {
closeFtpClient(ftpClient);
closeStream(os);
}
return flag;
}
}SFTPUtil
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>import com.jcraft.jsch.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Properties;
import java.util.Vector;
@Component
public class SFTPUtil {
private static final Logger logger = LoggerFactory.getLogger(SFTPUtil.class);
private Session session = null;
private ChannelSftp channel = null;
private int timeout = 60000;
/**
* 連接sftp服務(wù)器
*/
public boolean connect(String ftpUsername, String ftpAddress, int ftpPort, String ftpPassword) {
boolean isSuccess = false;
if (channel != null) {
System.out.println("通道不為空");
return false;
}
//創(chuàng)建JSch對(duì)象
JSch jSch = new JSch();
try {
// 根據(jù)用戶(hù)名,主機(jī)ip和端口獲取一個(gè)Session對(duì)象
session = jSch.getSession(ftpUsername, ftpAddress, ftpPort);
//設(shè)置密碼
session.setPassword(ftpPassword);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
//為Session對(duì)象設(shè)置properties
session.setConfig(config);
//設(shè)置超時(shí)
session.setTimeout(timeout);
//通過(guò)Session建立連接
session.connect();
System.out.println("Session連接成功");
// 打開(kāi)SFTP通道
channel = (ChannelSftp) session.openChannel("sftp");
// 建立SFTP通道的連接
channel.connect();
System.out.println("通道連接成功");
isSuccess = true;
} catch (JSchException e) {
logger.error("連接服務(wù)器異常", e);
}
return isSuccess;
}
/**
* 關(guān)閉連接
*/
public void close() {
//操作完畢后,關(guān)閉通道并退出本次會(huì)話
if (channel != null && channel.isConnected()) {
channel.disconnect();
}
if (session != null && session.isConnected()) {
session.disconnect();
}
}
/**
* 文件上傳
* 采用默認(rèn)的傳輸模式:OVERWRITE
* @param src 輸入流
* @param dst 上傳路徑
* @param fileName 上傳文件名
*
* @throws SftpException
*/
public boolean upLoadFile(InputStream src, String dst, String fileName) throws SftpException {
boolean isSuccess = false;
try {
if(createDir(dst)) {
channel.put(src, fileName);
isSuccess = true;
}
} catch (SftpException e) {
logger.error(fileName + "文件上傳異常", e);
}
return isSuccess;
}
/**
* 創(chuàng)建一個(gè)文件目錄
*
* @param createpath 路徑
* @return
*/
public boolean createDir(String createpath) {
boolean isSuccess = false;
try {
if (isDirExist(createpath)) {
channel.cd(createpath);
return true;
}
String pathArry[] = createpath.split("/");
StringBuffer filePath = new StringBuffer("/");
for (String path : pathArry) {
if (path.equals("")) {
continue;
}
filePath.append(path + "/");
if (isDirExist(filePath.toString())) {
channel.cd(filePath.toString());
} else {
// 建立目錄
channel.mkdir(filePath.toString());
// 進(jìn)入并設(shè)置為當(dāng)前目錄
channel.cd(filePath.toString());
}
}
channel.cd(createpath);
isSuccess = true;
} catch (SftpException e) {
logger.error("目錄創(chuàng)建異常!", e);
}
return isSuccess;
}
/**
* 判斷目錄是否存在
* @param directory 路徑
* @return
*/
public boolean isDirExist(String directory) {
boolean isSuccess = false;
try {
SftpATTRS sftpATTRS = channel.lstat(directory);
isSuccess = true;
return sftpATTRS.isDir();
} catch (Exception e) {
if (e.getMessage().toLowerCase().equals("no such file")) {
isSuccess = false;
}
}
return isSuccess;
}
/**
* 重命名指定文件或目錄
*
*/
public boolean rename(String oldPath, String newPath) {
boolean isSuccess = false;
try {
channel.rename(oldPath, newPath);
isSuccess = true;
} catch (SftpException e) {
logger.error("重命名指定文件或目錄異常", e);
}
return isSuccess;
}
/**
* 列出指定目錄下的所有文件和子目錄。
*/
public Vector ls(String path) {
try {
Vector vector = channel.ls(path);
return vector;
} catch (SftpException e) {
logger.error("列出指定目錄下的所有文件和子目錄。", e);
}
return null;
}
/**
* 刪除文件
*
* @param directory linux服務(wù)器文件地址
* @param deleteFile 文件名稱(chēng)
*/
public boolean deleteFile(String directory, String deleteFile) {
boolean isSuccess = false;
try {
channel.cd(directory);
channel.rm(deleteFile);
isSuccess = true;
} catch (SftpException e) {
logger.error("刪除文件失敗", e);
}
return isSuccess;
}
/**
* 下載文件
*
* @param directory 下載目錄
* @param downloadFile 下載的文件
* @param saveFile 下載到本地路徑
*/
public boolean download(String directory, String downloadFile, String saveFile) {
boolean isSuccess = false;
try {
channel.cd(directory);
File file = new File(saveFile);
channel.get(downloadFile, new FileOutputStream(file));
isSuccess = true;
} catch (SftpException e) {
logger.error("下載文件失敗", e);
} catch (FileNotFoundException e) {
logger.error("下載文件失敗", e);
}
return isSuccess;
}
}問(wèn)題
文件超出默認(rèn)大小
#單文件上傳最大大小,默認(rèn)1Mb
spring.http.multipart.maxFileSize=100Mb
#多文件上傳時(shí)最大大小,默認(rèn)10Mb
spring.http.multipart.maxRequestSize=500MB
到此這篇關(guān)于Java連接服務(wù)器的兩種方式SFTP和FTP的文章就介紹到這了,更多相關(guān)Java SFTP和FTP內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mybatis-generator-gui根據(jù)需求改動(dòng)示例
這篇文章主要為大家介紹了mybatis-generator-gui根據(jù)需求改動(dòng)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
java 實(shí)現(xiàn)切割文件和合并文件的功能
這篇文章主要介紹了java 實(shí)現(xiàn)切割文件和合并文件的功能的相關(guān)資料,這里實(shí)現(xiàn)文件的切割的實(shí)現(xiàn)代碼和文件合并的實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-07-07
Springboot之如何統(tǒng)計(jì)代碼執(zhí)行耗時(shí)時(shí)間
這篇文章主要介紹了Springboot之如何統(tǒng)計(jì)代碼執(zhí)行耗時(shí)時(shí)間問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
IDEA2023 Maven3.9.1+Tomcat10.1.8配置并搭建Servlet5.0的框架實(shí)現(xiàn)
本文主要介紹了IDEA2023 Maven3.9.1+Tomcat10.1.8配置并搭建Servlet5.0的框架實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
Java IO 之文件讀寫(xiě)簡(jiǎn)單實(shí)例
這篇文章主要介紹了Java IO 之文件讀寫(xiě)簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-06-06
java將一個(gè)目錄下的所有數(shù)據(jù)復(fù)制到另一個(gè)目錄下
這篇文章主要為大家詳細(xì)介紹了java將一個(gè)目錄下的所有數(shù)據(jù)復(fù)制到另一個(gè)目錄下,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08
解決Java包裝類(lèi)比較時(shí)遇到的問(wèn)題
所謂包裝類(lèi)的作用就是將原始數(shù)據(jù)類(lèi)型轉(zhuǎn)換成引用數(shù)據(jù)類(lèi)型,下面這篇文章主要給大家介紹了關(guān)于在Java包裝類(lèi)比較時(shí)遇到的問(wèn)題的解決方法,文中給出了詳細(xì)的示例代碼,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-09-09

