項目中用到了FTP的文件上傳與下載,於是網上搜索代碼,覺得(https://www.cnblogs.com/yingyujyf/p/6933823.html)此博主代碼寫的挺清晰,就把博主的代碼copy了過來,因爲本需求不需要將FTP文件下載到本地,只需要獲取文件內容,所以略加改造,直接上代碼。
用到的jar:
commons-net-1.4.1.jar
maven下載
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>1.4.1</version>
</dependency>
ftp工具類:
package cn.com.jit.signhp.utils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.com.jit.cloud.common.exception.BaseException;
public class FtpUtil {
private static Logger logger = LoggerFactory.getLogger(FtpUtil.class);
/**
* 獲取FTPClient對象
*
* @param ftpHost FTP主機服務器
* @param ftpPassword FTP 登錄密碼
* @param ftpUserName FTP登錄用戶名
* @param ftpPort FTP端口 默認爲21
* @return
*/
public static FTPClient getFTPClient(String ftpHost, String ftpUserName,
String ftpPassword, int ftpPort) {
FTPClient ftpClient = new FTPClient();
try {
ftpClient = new FTPClient();
ftpClient.connect(ftpHost, ftpPort);// 連接FTP服務器
ftpClient.login(ftpUserName, ftpPassword);// 登陸FTP服務器
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
ftpClient.disconnect();
logger.error("未連接到FTP,用戶名或密碼錯誤。");
} else {
logger.info("FTP connection success");
}
} catch (SocketException e) {
e.printStackTrace();
logger.error("FTP的IP地址可能錯誤,請正確配置。");
} catch (IOException e) {
logger.error("FTP的IP地址可能錯誤,請正確配置。");
}
return ftpClient;
}
/*
* 從FTP服務器獲取文件
*
* @param ftpHost FTP IP地址
* @param ftpUserName FTP 用戶名
* @param ftpPassword FTP用戶名密碼
* @param ftpPort FTP端口
* @param ftpPath FTP服務器中文件所在路徑 格式: /ftptest/aa.pdf
*/
public byte[] getFtpFileBytes(String ftpHost, String ftpUserName,
String ftpPassword, int ftpPort, String ftpPath) {
FTPClient ftpClient = null;
try {
ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
ftpClient.setControlEncoding("UTF-8"); // 中文支持
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); // 使用二進制保存方式
/*
* 這個方法的意思就是每次數據連接之前,ftp client告訴ftp server開通一個端口來傳輸數據。
* 爲什麼要這樣做呢,因爲ftp server可能每次開啓不同的端口來傳輸數據,
* 但是在linux上,由於安全限制,可能某些端口沒有開啓,所以就出現阻塞。
*/
ftpClient.enterLocalPassiveMode();
InputStream inputStream = ftpClient.retrieveFileStream(ftpPath);
if(null == inputStream) {
logger.error("沒有找到" + ftpPath + "文件");
}
byte[] bytes = IOUtils.toByteArray(inputStream);
inputStream.close();
ftpClient.logout();
return bytes;
} catch (FileNotFoundException e) {
logger.error("沒有找到" + ftpPath + "文件");
} catch (SocketException e) {
logger.error("連接FTP失敗.");
} catch (IOException e) {
logger.error("文件讀取錯誤。");
}
}
/*
* 從FTP服務器下載文件
*
* @param ftpHost FTP IP地址
* @param ftpUserName FTP 用戶名
* @param ftpPassword FTP用戶名密碼
* @param ftpPort FTP端口
* @param ftpPath FTP服務器中文件所在路徑 格式: ftptest/aa
* @param localPath 下載到本地的位置 格式:H:/download
* @param fileName 文件名稱
*/
public void downloadFtpFile(String ftpHost, String ftpUserName,
String ftpPassword, int ftpPort, String ftpPath, String localPath,
String fileName) {
FTPClient ftpClient = null;
try {
ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
ftpClient.setControlEncoding("UTF-8"); // 中文支持
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); // 使用二進制保存方式
ftpClient.enterLocalPassiveMode();
ftpClient.changeWorkingDirectory(ftpPath);
File localFile = new File(localPath + File.separatorChar + fileName);
OutputStream os = new FileOutputStream(localFile);
ftpClient.retrieveFile(fileName, os);
os.close();
ftpClient.logout();
}catch (FileNotFoundException e) {
logger.error("沒有找到" + fileName + "文件");
throw new BaseException("FF1C1807", fileName);
} catch (SocketException e) {
logger.error("連接FTP失敗.");
throw new BaseException("FF1C1808");
} catch (IOException e) {
logger.error("文件讀取錯誤。");
throw new BaseException("FF1C1809");
}
}
/**
* Description: 向FTP服務器上傳文件
* @param ftpHost FTP服務器hostname
* @param ftpUserName 賬號
* @param ftpPassword 密碼
* @param ftpPort 端口
* @param ftpPath FTP服務器中文件所在路徑 格式: ftptest/aa
* @param fileName ftp文件名稱
* @param input 文件流
* @return 成功返回true,否則返回false
*/
public boolean uploadFile(String ftpHost, String ftpUserName,
String ftpPassword, int ftpPort, String ftpPath,
String fileName,InputStream input) {
boolean success = false;
FTPClient ftpClient = null;
try {
int reply;
ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
return success;
}
ftpClient.setControlEncoding("UTF-8"); // 中文支持
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); // 使用二進制保存方式
ftpClient.enterLocalPassiveMode();
ftpClient.changeWorkingDirectory(ftpPath);
ftpClient.storeFile(fileName, input);
input.close();
ftpClient.logout();
success = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException ioe) {
}
}
}
return success;
}
public static void main(String[] args) {
String ftpHost = "127.0.0.1";
String ftpUserName = "xxx";
String ftpPassword = "xxx";
int ftpPort = 21;
String ftpPath = "/xxx/1.txt";
new FtpUtil().getFtpFileBytes(ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath);
}
}