1、maven工程中加入最新的commons-net包:
<!-- ftp上傳文件 -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.5</version>
</dependency>
2、FTPUtil.java:
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 java.io.*;
/**
* Created by ssl on 2017/8/7.
*/
public class FTPUtil {
/**
* 上傳文件(可供Action/Controller層使用)
*
* @param hostname FTP服務器地址
* @param port FTP服務器端口號
* @param username FTP登錄帳號
* @param password FTP登錄密碼
* @param pathname FTP服務器保存目錄
* @param fileName 上傳到FTP服務器後的文件名稱
* @param inputStream 輸入文件流
* @return
*/
public static boolean uploadFile(String hostname, int port, String username, String password, String pathname,
String fileName, InputStream inputStream) throws Exception {
boolean flag = false;
FTPClient ftpClient = new FTPClient();
ftpClient.setControlEncoding("UTF-8");
try {
//連接FTP服務器
ftpClient.connect(hostname, port);
//登錄FTP服務器
ftpClient.login(username, password);
//是否成功登錄FTP服務器
int replyCode = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
return flag;
}
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.makeDirectory(pathname);
ftpClient.changeWorkingDirectory(pathname);
ftpClient.storeFile(fileName, inputStream);
ftpClient.logout();
flag = true;
} catch (Exception e) {
throw e;
} finally {
if (null != inputStream) {
inputStream.close();
}
if (null != ftpClient) {
ftpClient.disconnect();
}
}
return flag;
}
/**
* 上傳文件(可對文件進行重命名)
*
* @param hostname FTP服務器地址
* @param port FTP服務器端口號
* @param username FTP登錄帳號
* @param password FTP登錄密碼
* @param pathname FTP服務器保存目錄
* @param filename 上傳到FTP服務器後的文件名稱
* @param originfilename 待上傳文件的名稱(絕對地址)
* @return
*/
public static boolean uploadFileFromProduction(String hostname, int port, String username, String password,
String pathname, String filename, String originfilename) throws
Exception {
boolean flag = false;
InputStream inputStream = null;
try {
inputStream = new FileInputStream(new File(originfilename));
flag = uploadFile(hostname, port, username, password, pathname, filename, inputStream);
} catch (Exception e) {
throw e;
} finally {
if (null != inputStream) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return flag;
}
/**
* 上傳文件(不可以進行文件的重命名操作)
*
* @param hostname FTP服務器地址
* @param port FTP服務器端口號
* @param username FTP登錄帳號
* @param password FTP登錄密碼
* @param pathname FTP服務器保存目錄
* @param originfilename 待上傳文件的名稱(絕對地址)
* @return
*/
public static boolean uploadFileFromProduction(String hostname, int port, String username, String password,
String pathname, String originfilename) {
boolean flag = false;
InputStream inputStream = null;
try {
String fileName = new File(originfilename).getName();
inputStream = new FileInputStream(new File(originfilename));
flag = uploadFile(hostname, port, username, password, pathname, fileName, inputStream);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != inputStream) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return flag;
}
/**
* 刪除文件
*
* @param hostname FTP服務器地址
* @param port FTP服務器端口號
* @param username FTP登錄帳號
* @param password FTP登錄密碼
* @param pathname FTP服務器保存目錄
* @param filename 要刪除的文件名稱
* @return
*/
public static boolean deleteFile(String hostname, int port, String username, String password, String pathname,
String filename) {
boolean flag = false;
FTPClient ftpClient = new FTPClient();
try {
//連接FTP服務器
ftpClient.connect(hostname, port);
//登錄FTP服務器
ftpClient.login(username, password);
//驗證FTP服務器是否登錄成功
int replyCode = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
return flag;
}
//切換FTP目錄
ftpClient.changeWorkingDirectory(pathname);
ftpClient.dele(filename);
ftpClient.logout();
flag = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.logout();
} catch (IOException e) {
}
}
}
return flag;
}
/**
* 下載文件
*
* @param hostname FTP服務器地址
* @param port FTP服務器端口號
* @param username FTP登錄帳號
* @param password FTP登錄密碼
* @param pathname FTP服務器文件目錄
* @param filename 文件名稱
* @param localpath 下載後的文件路徑
* @return
*/
public static boolean downloadFile(String hostname, int port, String username, String password, String pathname,
String filename, String localpath) throws Exception {
boolean success = false;
OutputStream out = null;
InputStream in = null;
FTPClient ftp = new FTPClient();//org.apache.commons.net.ftp
try {
int reply;
if (port > -1) {
ftp.connect(hostname, port);
} else {
ftp.connect(hostname);//ftp默認的端口是21
}
//很多人寫的是用ftp.getReplyCode()給獲取連接的返回值,但是這樣會導致storeFileStream返回null
ftp.login(username, password);
ftp.enterLocalActiveMode();
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return success;
}
//切換目錄 此處可以判斷,切換失敗就說明ftp上面沒有這個路徑(對路徑名進行轉碼,解決中文亂碼問題)
boolean flag = ftp.changeWorkingDirectory(new String(pathname.getBytes(), FTP.DEFAULT_CONTROL_ENCODING));
if (!flag) {
throw new Exception("目錄[" + pathname + "]不存在");
}
FTPFile[] fs = ftp.listFiles();
for (int i = 0; i < fs.length; i++) {
FTPFile ff = fs[i];
if (!ff.getName().equals(new String(filename.getBytes(), FTP.DEFAULT_CONTROL_ENCODING))) {
continue;
}
String outFileName = ff.getName();
//創建本地的文件時候要把編碼格式轉回來
//String localFileName = new String(ff.getName().getBytes("ISO-8859-1"), "UTF-8");
File localFile = new File(localpath.concat(File.separator).concat(filename));
out = new FileOutputStream(localFile);
in = ftp.retrieveFileStream(outFileName);
byte[] byteArray = new byte[4096];
int read = 0;
while ((read = in.read(byteArray)) != -1) {
out.write(byteArray, 0, read);
}
//這句很重要 要多次操作這個ftp的流的通道,要等他的每次命令完成
ftp.completePendingCommand();
out.flush();
ftp.logout();
success = true;
}
} catch (Exception e) {
throw e;
} finally {
if (null != out)
out.close();
if (null != in)
in.close();
if (ftp.isConnected()) {
ftp.disconnect();
}
}
return success;
}
}