依赖包:
<dependency>
<groupId>commons-netgroupId>
<artifactId>commons-netartifactId>
<version>3.3version>
dependency>
FtpUtils:
@Slf4j
public class FtpUtils {
/**
* Connect to FTP server.
*
* @param host FTP server address or name, port, user name, user password
* @throws IOException on I/O errors
*/
private static boolean connect(FTPClient ftpClient, Host host) throws IOException {
if (ftpClient == null) {
return false;
}
// Connect to server.
try {
// 解决上传文件时文件名乱码
ftpClient.setControlEncoding("UTF-8");
ftpClient.connect(host.getHost(), host.getPort());
} catch (IOException ex) {
throw new IOException("Can't find FTP server '" + host.getHost() + "'");
}
// Check rsponse after connection attempt.
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
disconnect(ftpClient);
throw new IOException("Can't connect to server '" + host.getHost() + "'");
}
// Login.
if (!ftpClient.login(host.getUserName(), host.getPassword())) {
disconnect(ftpClient);
throw new IOException("Can't login to server '" + host.getHost() + "'");
}
// Set data transfer mode.
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
//ftp.setFileType(FTP.ASCII_FILE_TYPE);
// Use passive mode to pass firewalls.
ftpClient.enterLocalPassiveMode();
return true;
}
/**c
* Disconnect from the FTP server
*
* @throws IOException on I/O errors
*/
private static void disconnect(FTPClient ftpClient) throws IOException {
if (ftpClient != null && ftpClient.isConnected()) {
try {
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException ignored) {
}
}
}
/**
* Get file from ftp server into given output stream
*
* @param ftpFileName file name on ftp server
* @param out OutputStream
* @throws IOException
*/
public static void retrieveFile(Host host, String ftpFileName, OutputStream out) throws IOException {
FTPClient ftpClient = null;
try {
ftpClient = new FTPClient();
connect(ftpClient, host);
// Get file info.
FTPFile[] fileInfoArray = ftpClient.listFiles(ftpFileName);
if (fileInfoArray == null || fileInfoArray.length == 0) {
throw new FileNotFoundException("File '" + ftpFileName + "' was not found on FTP server.");
}
// Check file size.
FTPFile fileInfo = fileInfoArray[0];
long size = fileInfo.getSize();
if (size > Integer.MAX_VALUE) {
throw new IOException("File '" + ftpFileName + "' is too large.");
}
// Download file.
if (!ftpClient.retrieveFile(ftpFileName, out)) {
throw new IOException("Error loading file '" + ftpFileName + "' from FTP server. Check FTP permissions and path.");
}
out.flush();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException ignored) {
}
disconnect(ftpClient);
}
}
public static InputStream retrieveFile(Host host, String ftpFileName) throws IOException {
FTPClient ftpClient = new FTPClient();
connect(ftpClient, host);
// Get file info.
FTPFile[] fileInfoArray = ftpClient.listFiles(ftpFileName);
if (fileInfoArray == null || fileInfoArray.length == 0) {
throw new FileNotFoundException("File '" + ftpFileName + "' was not found on FTP server.");
}
// Check file size.
FTPFile fileInfo = fileInfoArray[0];
long size = fileInfo.getSize();
if (size > Integer.MAX_VALUE) {
throw new IOException("File '" + ftpFileName + "' is too large.");
}
// get InputStream
InputStream inputStream = ftpClient.retrieveFileStream(ftpFileName);
disconnect(ftpClient);
return inputStream;
}
/**
* Put file on ftp server from given input stream
*
* @param ftpFileName file name on ftp server
* @param in InputStream
* @throws IOException
*/
public static boolean storeFile(Host host, String path, String ftpFileName, InputStream in) throws IOException {
FTPClient ftpClient = null;
try {
ftpClient = new FTPClient();
connect(ftpClient, host);
createDirectory(ftpClient, path);
if (!ftpClient.storeFile(ftpFileName, in)) {
throw new IOException("Can't upload file '" + ftpFileName + "' to FTP server. Check FTP permissions and path.");
}
return true;
} finally {
try {
in.close();
} catch (IOException ignored) {
}
disconnect(ftpClient);
}
}
/**
* Delete the file from the FTP server.
*
* @param ftpFileName server file name (with absolute path)
* @throws IOException on I/O errors
*/
public void deleteFile(Host host, String ftpFileName) throws IOException {
FTPClient ftpClient = new FTPClient();
connect(ftpClient, host);
if (!ftpClient.deleteFile(ftpFileName)) {
throw new IOException("Can't remove file '" + ftpFileName + "' from FTP server.");
}
disconnect(ftpClient);
}
/**
* Upload the file to the FTP server.
*
* @param remotePath server file name (with absolute path)
* @param localFile local file to upload
* @throws IOException on I/O errors
*/
public static void upload(Host host, String remotePath, String fileName, File localFile) throws IOException {
// File check.
if (!localFile.exists()) {
throw new IOException("Can't upload '" + localFile.getAbsolutePath() + "'. This file doesn't exist.");
}
FTPClient ftpClient = new FTPClient();
connect(ftpClient, host);
// Upload.
try (InputStream in = new BufferedInputStream(new FileInputStream(localFile))) {
createDirectory(ftpClient, remotePath);
if (!ftpClient.storeFile(fileName, in)) {
throw new IOException("Can't upload file '" + remotePath + "' to FTP server. Check FTP permissions and path.");
}
}
disconnect(ftpClient);
}
private static void createDirectory(FTPClient ftpClient, String remote) throws IOException {
String directory = remote + "/";
if ("/".equalsIgnoreCase(directory) || ftpClient.changeWorkingDirectory(directory)) {
return;
}
// 如果远程目录不存在,则递归创建远程服务器目录
int start;
int end;
if (directory.startsWith("/")) {
start = 1;
} else {
start = 0;
}
end = directory.indexOf("/", start);
String path = "";
do {
String subDirectory = remote.substring(start, end);
path = path + "/" + subDirectory;
// 不存在 -> 创建
if (!existFile(ftpClient, path) && !makeDirectory(ftpClient, subDirectory)) {
log.debug("创建目录[" + subDirectory + "]失败");
}
ftpClient.changeWorkingDirectory(subDirectory);
start = end + 1;
end = directory.indexOf("/", start);
// 检查所有目录是否创建完毕
} while (end > start);
}
/**
* 判断ftp服务器文件是否存在
*
* @param path 路径
* @return 是否存在
*/
private static boolean existFile(FTPClient ftpClient, String path) throws IOException {
return ftpClient.listFiles(path).length > 0;
}
/**
* 创建目录
*
* @param dir
* @return
*/
private static boolean makeDirectory(FTPClient ftpClient, String dir) {
boolean flag = true;
try {
flag = ftpClient.makeDirectory(dir);
if (flag) {
log.debug("创建文件夹" + dir + " 成功!");
} else {
log.debug("创建文件夹" + dir + " 失败!");
}
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
/**
* Download the file from the FTP server.
*
* @param ftpFileName server file name (with absolute path)
* @param localFile local file to download into
* @throws IOException on I/O errors
*/
public static void download(Host host, String ftpFileName, File localFile) throws IOException {
FTPClient ftpClient = new FTPClient();
connect(ftpClient, host);
// Download.
// Get file info.
FTPFile[] fileInfoArray = ftpClient.listFiles(ftpFileName);
if (fileInfoArray == null || fileInfoArray.length == 0) {
throw new FileNotFoundException("File " + ftpFileName + " was not found on FTP server.");
}
// Check file size.
FTPFile fileInfo = fileInfoArray[0];
long size = fileInfo.getSize();
if (size > Integer.MAX_VALUE) {
throw new IOException("File " + ftpFileName + " is too large.");
}
try (OutputStream out = new BufferedOutputStream(new FileOutputStream(localFile))) {
// Download file.
if (!ftpClient.retrieveFile(ftpFileName, out)) {
throw new IOException("Error loading file " + ftpFileName + " from FTP server. Check FTP permissions and path.");
}
out.flush();
} finally {
disconnect(ftpClient);
}
}
/**
* List the file name in the given FTP directory.
*
* @param filePath absolute path on the server
* @return files relative names list
* @throws IOException on I/O errors
*/
public List<String> listFileNames(Host host, String filePath) throws IOException {
FTPClient ftpClient = new FTPClient();
connect(ftpClient, host);
List<String> fileList = new ArrayList<>();
FTPFile[] ftpFiles = ftpClient.listFiles(filePath);
for (int i = 0; ftpFiles != null && i < ftpFiles.length; i++) {
FTPFile ftpFile = ftpFiles[i];
if (ftpFile.isFile()) {
fileList.add(ftpFile.getName());
}
}
disconnect(ftpClient);
return fileList;
}
/**
* List the files in the given FTP directory.
*
* @param filePath directory
* @return list
* @throws IOException
*/
public List<FTPFile> listFiles(Host host, String filePath) throws IOException {
FTPClient ftpClient = new FTPClient();
connect(ftpClient, host);
List<FTPFile> fileList = new ArrayList<>();
FTPFile[] ftpFiles = ftpClient.listFiles(filePath);
for (int i = 0; ftpFiles != null && i < ftpFiles.length; i++) {
FTPFile ftpFile = ftpFiles[i];
fileList.add(ftpFile);
}
disconnect(ftpClient);
return fileList;
}
/**
* Send an FTP Server site specific command
*
* @param args site command arguments
* @throws IOException on I/O errors
*/
public void sendSiteCommand(Host host, String args) throws IOException {
FTPClient ftpClient = new FTPClient();
connect(ftpClient, host);
if (!ftpClient.isConnected()) {
return;
}
try {
ftpClient.sendSiteCommand(args);
} finally {
disconnect(ftpClient);
}
}
/**
* Get current directory on ftp server
*
* @return current directory
*/
public String printWorkingDirectory(Host host) throws IOException {
FTPClient ftpClient = new FTPClient();
connect(ftpClient, host);
if (!ftpClient.isConnected()) {
return "";
}
try {
return ftpClient.printWorkingDirectory();
} finally {
disconnect(ftpClient);
}
}
public static class Host {
private String host;
private int port;
private String userName;
private String password;
public Host(String host, int port, String userName, String password) {
this.host = host;
this.port = port;
this.userName = userName;
this.password = password;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
public static void main(String[] args) throws Exception {
Host host = new Host("192.168.200.13", 21, "test", "test@123");
FtpUtils.retrieveFile(host, "/baseinfo/杭州/人员信息/QQ截图20200722144326.png");
File file = new File("C:/Users/epsoft/Desktop/QQ截图20200722144326.png");
FtpUtils.storeFile(host, "/baseinfo/杭州/人员信息", "QQ截图20200722144326.png", new FileInputStream(file));
}
}