FTP 是File Transfer Protocol(文件傳輸協議)的英文簡稱,而中文簡稱爲“文傳協議”。用於Internet上的控制文件的雙向傳輸。同時,它也是一個應用程序(Application)。基於不同的操作系統有不同的FTP應用程序,而所有這些應用程序都遵守同一種協議以傳輸文件。在FTP的使用當中,用戶經常遇到兩個概念:"下載"(Download)和"上傳"(Upload)。"下載"文件就是從遠程主機拷貝文件至自己的計算機上;"上傳"文件就是將文件從自己的計算機中拷貝至遠程主機上。用Internet語言來說,用戶可通過客戶機程序向(從)遠程主機上傳(下載)文件。 -- 摘自百度百科
import it.sauronsoftware.ftp4j.FTPClient;
import it.sauronsoftware.ftp4j.FTPException;
import it.sauronsoftware.ftp4j.FTPFile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.Properties;
import org.springframework.util.StringUtils;
import com.ibm.icu.text.SimpleDateFormat;
/**
* FTP文件處理工具類
* @author yangnuo
*/
public class FTPUtils {
private static FTPUtils ftp;
/**
* FTP服務地址
*/
private static String ADDRESS = "";//PropUtils.getString("ftp_server_address"); http:\\192.168.1.42:21
/**
* FTP登錄用戶名
*/
private static String USERNAME = ""; //PropUtils.getString("ftp_server_username"); nuohy
/**
* FTP登錄密碼
*/
private static String PASSWORD = ""; //PropUtils.getString("ftp_server_password"); 123456
/**
* 本地 掃描路徑 某個文件夾
*/
private static String PATH = "";
/**
* 構造方法
*/
public FTPUtils() {
initPath();
}
/**
* 實例化對象
*
* @return
*/
public static FTPUtils getInstance() {
if (ftp == null) {
ftp = new FTPUtils();
}
return ftp;
}
/**
* 獲取FTP客戶端對象
*
* @return
* @throws Exception
*/
public FTPClient getClient() throws Exception {
FTPClient client = new FTPClient();
client.setCharset("utf-8");
client.setType(FTPClient.TYPE_BINARY);
URL url = new URL(FTPUtils.ADDRESS);
int port = url.getPort() < 1 ? 21 : url.getPort();
client.connect(url.getHost(), port);
client.login(FTPUtils.USERNAME, FTPUtils.PASSWORD);
return client;
}
/**
* 註銷客戶端連接
*
* @param client
* FTP客戶端對象
* @throws Exception
*/
public void logout(FTPClient client) throws Exception {
boolean f = true;
if (client == null){
f = true;
}
if (client.isConnected()) {
try {
client.disconnect(true);
f = true;
} catch (Exception e) {
try {
System.out.println("開始強制退出...");
client.disconnect(false);
} catch (Exception e1) {
e1.printStackTrace();
f = false;
}
}
}
/*if (client != null) {
try {
// 有些FTP服務器未實現此功能,若未實現則會出錯
client.logout(); // 退出登錄
} catch (FTPException fe) {
System.out.println("1推出出現異常,原因:["+fe.getMessage()+"]");
} catch (Exception e) {
System.out.println("2推出出現異常,原因:["+e.getMessage()+"]");
throw e;
} finally {
if (client.isConnected()) { // 斷開連接
client.disconnect(true);
}
}
}*/
}
/**
* 創建目錄
*
* @param client
* FTP客戶端對象
* @param dir
* 目錄
* @throws Exception
*/
private void mkdirs(FTPClient client, String dir) throws Exception {
if (dir == null) {
return;
}
dir = dir.replace("//", "/");
String[] dirs = dir.split("/");
for (int i = 0; i < dirs.length; i++) {
dir = dirs[i];
if (!StringUtils.isEmpty(dir)) {
if (!exists(client, dir)) {
client.createDirectory(dir);
}
client.changeDirectory(dir);
}
}
}
/**
* 獲取FTP目錄
*
* @param url
* 原FTP目錄
* @param dir
* 目錄
* @return
* @throws Exception
*/
private URL getURL(URL url, String dir) throws Exception {
String path = url.getPath();
if (!path.endsWith("/") && !path.endsWith("//")) {
path += "/";
}
dir = dir.replace("//", "/");
if (dir.startsWith("/")) {
dir = dir.substring(1);
}
path += dir;
return new URL(url, path);
}
/**
* 獲取FTP目錄
*
* @param dir
* 目錄
* @return
* @throws Exception
*/
private URL getURL(String dir) throws Exception {
return getURL(new URL(FTPUtils.ADDRESS), dir);
}
/**
* 判斷文件或目錄是否存在
*
* @param client
* FTP客戶端對象
* @param dir
* 文件或目錄
* @return
* @throws Exception
*/
private boolean exists(FTPClient client, String dir) throws Exception {
return getFileType(client, dir) != -1;
}
/**
* 判斷當前爲文件還是目錄
*
* @param client
* FTP客戶端對象
* @param dir
* 文件或目錄
* @return -1、文件或目錄不存在 0、文件 1、目錄
* @throws Exception
*/
private int getFileType(FTPClient client, String dir) throws Exception {
FTPFile[] files = null;
try {
files = client.list(dir);
} catch (Exception e) {
return -1;
}
if (files.length > 1) {
return FTPFile.TYPE_DIRECTORY;
} else if (files.length == 1) {
FTPFile f = files[0];
if (f.getType() == FTPFile.TYPE_DIRECTORY) {
return FTPFile.TYPE_DIRECTORY;
}
String path = dir + "/" + f.getName();
try {
int len = client.list(path).length;
if (len == 1) {
return FTPFile.TYPE_DIRECTORY;
} else {
return FTPFile.TYPE_FILE;
}
} catch (Exception e) {
return FTPFile.TYPE_FILE;
}
} else {
try {
client.changeDirectory(dir);
client.changeDirectoryUp();
return FTPFile.TYPE_DIRECTORY;
} catch (Exception e) {
return -1;
}
}
}
/**
* 上傳文件或目錄
*
* @param dir
* 目標文件
* @param del
* 是否刪除源文件,默認爲false
* @param file
* 文件或目錄對象數組
* @throws Exception
*/
public void upload(String dir, boolean del, File... files) throws Exception {
if (StringUtils.isEmpty(dir) || StringUtils.isEmpty(files)) {
return;
}
FTPClient client = null;
try {
client = getClient();
if(IsCreateDir(dir)){
mkdirs(client, dir); // 創建文件
}
client.changeDirectory(dir);
for (File file : files) {
if (file.isDirectory()) { // 上傳目錄
uploadFolder(client, getURL(dir), file, del);
} else {
client.upload(file); // 上傳文件
if (del) { // 刪除源文件
file.delete();
}
}
}
} finally {
logout(client);
}
}
/**
* 上傳文件或目錄
*
* @param dir
* 目標文件
* @param files
* 文件或目錄對象數組
* @throws Exception
*/
public void upload(String dir, File... files) throws Exception {
upload(dir, false, files);
}
/**
* 上傳文件或目錄
*
* @param dir
* 目標文件
* @param del
* 是否刪除源文件,默認爲false
* @param path
* 文件或目錄路徑數組
* @throws Exception
*/
public void upload(String dir, boolean del, String[] paths)throws Exception {
if (StringUtils.isEmpty(paths)) {
return;
}
File[] files = new File[paths.length];
for (int i = 0; i < paths.length; i++) {
files[i] = new File(paths[i]);
}
upload(dir, del, files);
}
/**
* 上傳文件或目錄
*
* @param dir
* 目標文件
* @param paths
* 文件或目錄路徑數組
* @throws Exception
*/
public void upload(String dir, String... paths) throws Exception {
upload(dir, false, paths);
}
/**
* 上傳目錄
*
* @param client
* FTP客戶端對象
* @param parentUrl
* 父節點URL
* @param file
* 目錄
* @throws Exception
*/
private void uploadFolder(FTPClient client, URL parentUrl, File file,
boolean del) throws Exception {
client.changeDirectory(parentUrl.getPath());
String dir = file.getName(); // 當前目錄名稱
URL url = getURL(parentUrl, dir);
if (!exists(client, url.getPath())) { // 判斷當前目錄是否存在
client.createDirectory(dir); // 創建目錄
}
client.changeDirectory(dir);
File[] files = file.listFiles(); // 獲取當前文件夾所有文件及目錄
for (int i = 0; i < files.length; i++) {
file = files[i];
if (file.isDirectory()) { // 如果是目錄,則遞歸上傳
uploadFolder(client, url, file, del);
} else { // 如果是文件,直接上傳
client.changeDirectory(url.getPath());
client.upload(file);
if (del) { // 刪除源文件
file.delete();
}
}
}
}
/**
* 刪除文件或目錄
*
* @param dir
* 文件或目錄數組
* @throws Exception
*/
public void delete(String... dirs) throws Exception {
if (StringUtils.isEmpty(dirs)) {
return;
}
FTPClient client = null;
try {
client = getClient();
int type = -1;
for (String dir : dirs) {
client.changeDirectory("/"); // 切換至根目錄
type = getFileType(client, dir); // 獲取當前類型
if (type == 0) { // 刪除文件
client.deleteFile(dir);
} else if (type == 1) { // 刪除目錄
deleteFolder(client, getURL(dir));
}
}
} finally {
logout(client);
}
}
/**
* 刪除目錄
*
* @param client
* FTP客戶端對象
* @param url
* FTP URL
* @throws Exception
*/
private void deleteFolder(FTPClient client, URL url) throws Exception {
String path = url.getPath();
client.changeDirectory(path);
FTPFile[] files = client.list();
String name = null;
for (FTPFile file : files) {
name = file.getName();
// 排除隱藏目錄
if (".".equals(name) || "..".equals(name)) {
continue;
}
if (file.getType() == FTPFile.TYPE_DIRECTORY) { // 遞歸刪除子目錄
deleteFolder(client, getURL(url, file.getName()));
} else if (file.getType() == FTPFile.TYPE_FILE) { // 刪除文件
client.deleteFile(file.getName());
}
}
client.changeDirectoryUp();
client.deleteDirectory(url.getPath()); // 刪除當前目錄
}
/**
* 下載文件或目錄
*
* @param localDir
* 本地存儲目錄
* @param dirs
* 文件或者目錄
* @throws Exception
*/
public void download(String localDir, String... dirs) throws Exception {
if (StringUtils.isEmpty(dirs)) {
return;
}
FTPClient client = null;
try {
client = getClient();
File folder = new File(localDir);
if (!folder.exists()) { // 如果本地文件夾不存在,則創建
folder.mkdirs();
}
int type = -1;
String localPath = null;
for (String dir : dirs) {
client.changeDirectory("/"); // 切換至根目錄
type = getFileType(client, dir); // 獲取當前類型
if (type == 0) { // 文件
localPath = localDir + "/" + new File(dir).getName();
client.download(dir, new File(localPath));
} else if (type == 1) { // 目錄
downloadFolder(client, getURL(dir), localDir);
}
}
} finally {
logout(client);
}
}
/**
* 下載文件夾
*
* @param client
* FTP客戶端對象
* @param url
* FTP URL
* @param localDir
* 本地存儲目錄
* @throws Exception
*/
private void downloadFolder(FTPClient client, URL url, String localDir) throws Exception {
String path = url.getPath();
client.changeDirectory(path);
// 在本地創建當前下載的文件夾
File folder = new File(localDir + "/" + new File(path).getName());
if (!folder.exists()) {
folder.mkdirs();
}
localDir = folder.getAbsolutePath();
FTPFile[] files = client.list();
String name = null;
for (FTPFile file : files) {
name = file.getName();
// 排除隱藏目錄
if (".".equals(name) || "..".equals(name)) {
continue;
}
if (file.getType() == FTPFile.TYPE_DIRECTORY) { // 遞歸下載子目錄
downloadFolder(client, getURL(url, file.getName()), localDir);
} else if (file.getType() == FTPFile.TYPE_FILE) { // 下載文件
client.download(name, new File(localDir + "/" + name));
}
}
client.changeDirectoryUp();
}
/**
* 獲取目錄下所有文件
*
* @param dir
* 目錄
* @return
* @throws Exception
*/
public String[] list(String dir) throws Exception {
FTPClient client = null;
try {
client = getClient();
client.changeDirectory(dir);
String[] values = client.listNames();
if (values != null) {
// 將文件排序(忽略大小寫)
Arrays.sort(values, new Comparator<String>(){
public int compare(String val1, String val2) {
return val1.compareToIgnoreCase(val2);
}
});
}
return values;
} catch(FTPException fe) {
// 忽略文件夾不存在的情況
String mark = "code=550";
if (fe.toString().indexOf(mark) == -1) {
throw fe;
}
} finally {
logout(client);
}
return new String[0];
}
/**
* 判斷是否存在文件夾
* @param dir
* @return
*/
public boolean IsCreateDir(String dir){
FTPClient client = null;
boolean f = false;
try {
client = getClient();
try {
client.changeDirectory(dir);
client.changeDirectoryUp();
}catch (Exception e) {
f = true;
}
} catch (Exception e) {
}finally{
try {
logout(client);
} catch (Exception e) {
System.out.println("判斷是否存在文件夾時,關閉連接失敗!");
}
}
System.out.println("能否創建文件夾:"+f);
return f;
}
/**
* 初始化路徑
*/
public void initPath(){
if(!PATH.equals("")&&!ADDRESS.equals("")&&!USERNAME.equals("")&&!PASSWORD.equals("")){
return;
}
System.out.println("加載路徑");
InputStream in = this.getClass().getResourceAsStream("/App.properties");
Properties prop = new Properties();
try {
prop.load(in);
} catch (IOException e) {
e.printStackTrace();
System.out.println("讀取配置文件失敗!");
}
PATH = prop.getProperty("scanpath");
ADDRESS = prop.getProperty("address");
USERNAME = prop.getProperty("username");
PASSWORD = prop.getProperty("password");
}
/**
* 獲取文件夾下 所有的文件路徑
* @param path
* @return
*/
public String[] getFilePath(String path){
System.out.println("======");
if(path==null||path.equals("")){
System.out.println("PATH:"+PATH);
path = PATH;
}
String[] refilepath = new String[0];
try{
File file = new File(path);
File[] listFiles = file.listFiles();
for (File f : listFiles) {
if(f.isFile()){
String filename = f.getName();
String[] split = filename.split("_");
String timestr = split[1];
timestr = timestr.substring(0, 8);
int currentTime = Integer.parseInt(new SimpleDateFormat("yyyyMMdd").format(new Date()));
// System.out.println("split.length>"+split.length);
//只備份昨天的 數據
if(Integer.parseInt(timestr)==currentTime-1&&split.length==2){
refilepath = Arrays.copyOf(refilepath, refilepath.length+1);
refilepath[refilepath.length-1] = f.getAbsolutePath();
}
}
}
}catch(Exception e){
e.printStackTrace();
System.out.println("獲取路徑失敗!");
}
return refilepath;
}
/**
* 修改文件名字
* @return
*/
public boolean editFileName(String filepath,String newFileName){
try{
File file = new File(filepath);
file.renameTo(new File(file.getParent()+File.separator+newFileName));
// System.out.println("將"+file.getName()+"文件, 重命名爲:"+newFileName);
// System.out.println("新文件路徑:"+file.getParent()+File.separator+newFileName);
}catch(Exception e){
return false;
}
return true;
}
}
FTPUtils ftpUtils = new FTPUtils();
//獲取被掃描文件夾下所有符合上傳條件的文件路徑
String[] filePath = ftpUtils.getFilePath(null);
for (String string : filePath) {
File editfilename = new File(string);
try {
ftpUtils.upload("sql", new String[]{string});
System.out.println(editfilename.getName()+"上傳完成!");
} catch (Exception e) {
System.out.println(editfilename.getName()+"上傳失敗! 原因:["+e.getMessage()+"]");
e.printStackTrace();
}
if(ftpUtils.editFileName(string, editfilename.getName().split("\\.")[0]+"_1"+".sql")){
System.out.println("完成修改文件名!");
}
}
其中 ftpUtils.getFilePath(null); 這個方法是獲取某個文件夾下的所有.sql文件路徑+名稱的,傳入空值,表示使用配置的路徑。獲取到的文件名稱類似爲,xxx_20170224170400.sql,如果想要上傳其他的文件,只要改動這個方法即可。
scanpath=C\:/Users/admin/Desktop/ss/
#ftp服務器地址
address=http\://192.168.1.42:21
#用戶名
username=root
#密碼
password=123456