基于FTP4J組件的FTP操作客戶端
基于FTP4J組件的FTP操作客戶端,支持上傳、下載,兩臺FTP服務器文件流同步。
package com.matol.utilsimport it.sauronsoftware.ftp4j.FTPClient; import it.sauronsoftware.ftp4j.FTPDataTransferListener; import it.sauronsoftware.ftp4j.FTPFile;
import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List;
/**
- 基于FTP4J組件的FTP操作客戶端
ww */ public final class FTPToolkit { //單例模型 private FTPToolkit() { }
/**
- 創建FTP連接
- @param host 主機名或IP
- @param port ftp端口
- @param username ftp用戶名
- @param password ftp密碼
@return 一個單例客戶端 */ public static FTPClient ftpConn(String host, int port, String username, String password) { FTPClient client = new FTPClient(); try {
client.connect(host, port); client.login(username, password); client.setCharset("GBK"); client.setType(FTPClient.TYPE_BINARY);
} catch (Exception e) {
System.out.println("###[Error] FTPToolkit.ftpConn() "+e.getMessage());
} return client; }
/**
- 取得目錄下所有文件列表
- @param path
- @return
*/
public static List<FTPFile> getlistFiles(FTPClient client,String path) {
List<FTPFile> filesList = new ArrayList<FTPFile>();
try {
} catch (Exception e) {client.changeDirectory(path); FTPFile[] fileNames = client.list(); //.listNames(); if (null != fileNames) { for (FTPFile file : fileNames) { if(file.getType() == FTPFile.TYPE_FILE){ filesList.add(file); //System.out.println(file.getName()+" | "+file.getSize()+" | "+DateUtil.converDateToString(file.getModifiedDate(),DateUtil.defaultDatePattern)); } } }
} return filesList; } /**System.out.println("###[Error] FTPToolkit.getlistFiles()"+ e.getMessage());
- 取得目錄下所有文件列表
- @param path
@return */ public static List<String> getlistFileNames(FTPClient client,String path) { List<String> filesList = new ArrayList<String>(); try {
client.changeDirectory(path); String[] fileNames = client.listNames(); if (null != fileNames) { for (String file : fileNames) { filesList.add(path+"/"+file); //System.out.println(path+"/"+file); } }
} catch (Exception e) {
System.out.println("###[Error] FTPToolkit.getlistFileNames()"+ e.getMessage());
} return filesList; }
/**
- 根據文件路徑獲取文件流
- @param path
@return */ public static InputStream fetchInputStream(FTPClient client,String ftpFilePath,String ftpPath) { InputStream is = null; try {
String localFilePath = getFileName("ftptmp/"+ftpFilePath) + "_ftp.tmp"; File tempLocalFile = new File(localFilePath); if (!tempLocalFile.exists()) { tempLocalFile.createNewFile(); } client.download(ftpPath, tempLocalFile); is = new FileInputStream(tempLocalFile); //刪除臨時文件(由于不能關閉文件流,刪除臨時文件無效,所以最好使用deleteOnExit,外層程序使用文件流結束后,關閉流,自動刪除) //tempLocalFile.deleteOnExit();
} catch (Exception e) {
System.out.println("###[Error] FTPToolkit.fetchInputStream()"+e.getMessage());
} return is; }
/**
- 上傳文件到FTP
- @param ftpFilePath 要上傳到FTP的路徑
@param source 源數據 */ public static void uploadInputStream(FTPClient client,String ftpFilePath, InputStream ftpFile) { try { mkDirs(client,ftpFilePath.substring(0, ftpFilePath.lastIndexOf("/")));
client.upload(ftpFilePath, ftpFile, 0l, 0l, null); } catch (Exception e) { System.out.println("###[Error] FTPToolkit.uploadInputStream()"+e.getMessage()); }finally{ try {
//關閉文件流 ftpFile.close();
} catch (Exception e) {} } }
/**
* FTP下載文件到本地一個文件夾,如果本地文件夾不存在,則創建必要的目錄結構
* @param client FTP客戶端
* @param remoteFileName FTP文件
* @param localFolderPath 存的本地目錄
*/
public static void download(FTPClient client, String remoteFileName, String localFolderPath) {
try {
int x = isExist(client, remoteFileName);
MyFtpListener listener = MyFtpListener.instance("download");
File localFolder = new File(localFolderPath);
if (!localFolder.exists()) {
localFolder.mkdirs();
}
if (x == FTPFile.TYPE_FILE) {
String localfilepath = formatPath4File(localFolderPath+File.separator+new File(remoteFileName).getName());
if (listener != null) {
client.download(remoteFileName, new File(localfilepath), listener);
}else{
client.download(remoteFileName, new File(localfilepath));
}
}
} catch (Exception e) {
System.out.println("###[Error] FTPToolkit.download()"+e.getMessage());
}
}
//遞歸創建層級目錄(坑爹的問題,原本想著遞歸處理,后來才發現如此的簡單)
private static void mkDirs(FTPClient client,String p) throws Exception {
if (null == p) { return;}
if(p != null && !"".equals(p) && !"/".equals(p)){
String ps = "";
for(int i=0;i<p.split("/").length;i++){
ps += p.split("/")[i]+"/";
if (!isDirExist(client,ps)) {
client.createDirectory(ps);// 創建目錄
client.changeDirectory(ps);// 進入創建的目錄
System.out.println(">>>>> create directory:["+i+"]["+ps+"]");
}else{
//System.out.println("select directory:["+i+"]["+ps+"]");
}
}
}
}
//檢查目錄是否存在
private static boolean isDirExist(FTPClient client,String dir) {
try {
client.changeDirectory(dir);
} catch (Exception e) {
return false;
}
return true;
}
/**
* FTP上傳本地文件到FTP的一個目錄下
* @param client FTP客戶端
* @param localfilepath 本地文件路徑
* @param remoteFolderPath FTP上傳目錄
*/
public static void upload(FTPClient client, String localfilepath, String remoteFolderPath) {
try {
mkDirs(client,remoteFolderPath);
File localfile = new File(localfilepath);
upload(client, localfile, remoteFolderPath);
} catch (Exception e) {
System.out.println("###[Error] FTPToolkit.upload()"+e.getMessage());
}
}
/**
* FTP上傳本地文件到FTP的一個目錄下
* @param client FTP客戶端
* @param localfile 本地文件
* @param remoteFolderPath FTP上傳目錄
*/
public static void upload(FTPClient client, File localfile, String remoteFolderPath) {
remoteFolderPath = formatPath4FTP(remoteFolderPath);
MyFtpListener listener = MyFtpListener.instance("upload");
try {
client.changeDirectory(remoteFolderPath);
if (listener != null) {
client.upload(localfile, listener);
}else{
client.upload(localfile);
}
client.changeDirectory("/");
} catch (Exception e) {
System.out.println("###[Error] FTPToolkit.upload()"+e.getMessage());
}
}
/**
* 批量上傳本地文件到FTP指定目錄上
* @param client FTP客戶端
* @param localFilePaths 本地文件路徑列表
* @param remoteFolderPath FTP上傳目錄
*/
public static void uploadListPath(FTPClient client, List<String> localFilePaths, String remoteFolderPath) {
try {
remoteFolderPath = formatPath4FTP(remoteFolderPath);
client.changeDirectory(remoteFolderPath);
MyFtpListener listener = MyFtpListener.instance("uploadListPath");
for (String path : localFilePaths) {
File file = new File(path);
if (listener != null) {
client.upload(file, listener);
}else {
client.upload(file);
}
}
client.changeDirectory("/");
} catch (Exception e) {
System.out.println("###[Error] FTPToolkit.uploadListPath()"+e.getMessage());
}
}
/**
* 批量上傳本地文件到FTP指定目錄上
* @param client FTP客戶端
* @param localFiles 本地文件列表
* @param remoteFolderPath FTP上傳目錄
*/
public static void uploadListFile(FTPClient client, List<File> localFiles, String remoteFolderPath) {
try {
client.changeDirectory(remoteFolderPath);
remoteFolderPath = formatPath4FTP(remoteFolderPath);
MyFtpListener listener = MyFtpListener.instance("uploadListFile");
for (File file : localFiles) {
if (listener != null){
client.upload(file, listener);
}else{
client.upload(file);
}
}
client.changeDirectory("/");
} catch (Exception e) {
System.out.println("###[Error] FTPToolkit.uploadListFile() "+e.getMessage());
}
}
/**
* 判斷一個FTP路徑是否存在,如果存在返回類型(FTPFile.TYPE_DIRECTORY=1、FTPFile.TYPE_FILE=0、FTPFile.TYPE_LINK=2)
* @param client FTP客戶端
* @param remotePath FTP文件或文件夾路徑
* @return 存在時候返回類型值(文件0,文件夾1,連接2),不存在則返回-1
*/
public static int isExist(FTPClient client, String remotePath) {
int x = -1;
try {
remotePath = formatPath4FTP(remotePath);
FTPFile[] list = client.list(remotePath);
if (list.length > 1){
x = 1;
}else if (list.length == 1) {
FTPFile f = list[0];
if (f.getType() == FTPFile.TYPE_DIRECTORY) {
x = 1;
}
//假設推理判斷
String _path = remotePath + "/" + f.getName();
if(client.list(_path).length == 1){
x = 1;
}else{
x = 0;
}
} else {
client.changeDirectory(remotePath);
x = 1;
}
} catch (Exception e) {
x = -1;
System.out.println("###[Error] FTPToolkit.isExist() "+e.getMessage());
}
return x;
}
/**
* 關閉FTP連接,關閉時候像服務器發送一條關閉命令
* @param client FTP客戶端
* @return 關閉成功,或者鏈接已斷開,或者鏈接為null時候返回true,通過兩次關閉都失敗時候返回false
*/
public static boolean closeConn(FTPClient client) {
if (client == null) return true;
if (client.isConnected()) {
try {
client.disconnect(true);
return true;
} catch (Exception e) {
try {
client.disconnect(false);
} catch (Exception e1) {}
}
}
return true;
}
//###---------------------------------------------------------------------
/**
* 格式化文件路徑,將其中不規范的分隔轉換為標準的分隔符,并且去掉末尾的文件路徑分隔符。
* 本方法操作系統自適應
* @param path 文件路徑
* @return 格式化后的文件路徑
*/
public static String formatPath4File(String path) {
String reg0 = "\\\\+";
String reg = "\\\\+|/+";
String temp = path.trim().replaceAll(reg0, "/");
temp = temp.replaceAll(reg, "/");
if (temp.length() > 1 && temp.endsWith("/")) {
temp = temp.substring(0, temp.length() - 1);
}
temp = temp.replace('/', File.separatorChar);
return temp;
}
/**
* 格式化文件路徑,將其中不規范的分隔轉換為標準的分隔符
* 并且去掉末尾的"/"符號(適用于FTP遠程文件路徑或者Web資源的相對路徑)。
* @param path 文件路徑
* @return 格式化后的文件路徑
*/
public static String formatPath4FTP(String path) {
String reg0 = "\\\\+";
String reg = "\\\\+|/+";
String temp = path.trim().replaceAll(reg0, "/");
temp = temp.replaceAll(reg, "/");
if (temp.length() > 1 && temp.endsWith("/")) {
temp = temp.substring(0, temp.length() - 1);
}
return temp;
}
/**
* 獲取FTP路徑的父路徑,但不對路徑有效性做檢查
* @param path FTP路徑
* @return 父路徑,如果沒有父路徑,則返回null
*/
public static String genParentPath4FTP(String path) {
String f = new File(path).getParent();
if (f == null) {
return null;
}else {
return formatPath4FTP(f);
}
}
//###---------------------------------------------------------------------
//獲取指定目錄下的文件
public static File[] getPathFiles(String path){
File file = new File(path);
if (file.isDirectory()) {
File[] files = file.listFiles();
return files;
}
return null;
}
//刪除指定目錄下的臨時文件
public static void deleteFiles(String path){
File file = new File(path);
if (file.isDirectory()) {
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
//String name = files[i].getName();
//if(name.trim().toLowerCase().endsWith("_ftp.tmp")) {
//System.out.println(name + "\t");
//}
//清空臨時文件 _ftp.tmp
files[i].delete();
}
}
}
//截取文件名稱
public static String getFileName(String fileName){
String fs = "F"+System.currentTimeMillis();
try {
if(fileName != null && !"".equals(fileName)){
if(fileName.lastIndexOf("/") > 0 && fileName.lastIndexOf(".") > 0){
fs = fileName.substring(fileName.lastIndexOf("/")+1);
}else{
fs = fileName;
}
if(fs.length() >50){
fs = fs.substring(0,50);
}
return fs;
}else{
return fs;
}
} catch (Exception e) {
System.out.println("###[Error] FtpTools.getFileName()"+e.getMessage());
}
return fs;
}
public static void main(String args[]) throws Exception {
FTPClient f41 = FTPToolkit.ftpConn("129.2.8.31", 21, "root", "root31");
FTPClient f42 = FTPToolkit.ftpConn("129.2.8.32", 21, "root", "root32");
//InputStream in = FTPToolkit.fetchInputStream(f41,"/home/photofile/wenzi-003.jpg");
//FTPToolkit.uploadInputStream(f41,"/home/photofile/aa.jpg",in);
//FTPToolkit.upload(f41, "E:\\demo\\av1.jpg", "/home/photofile/10/20");
//FTPToolkit.download(f41, "/home/photofile/wenzi-100.jpg", "E:\\");
//FTPToolkit.getlistFiles(f41,"/home/photofile");
//文件流對流讀取操作
List<String> ls = null;//FTPToolkit.getlistFileNames(f41,"/home/photofile");
if(ls != null && ls.size() >0){
InputStream in=null;
for(int i =0;i<ls.size();i++){
//in = FTPToolkit.fetchInputStream(f41,ls.get(i));
if(in != null && in.available() > 0){
FTPToolkit.uploadInputStream(f42,"/home/wasadmin/photoSysTempFTP/"+getFileName(ls.get(i)),in);
f41.deleteFile(ls.get(i));
}
}
//清空項目下的臨時文件
FTPToolkit.deleteFiles("ftptmp");
}
FTPToolkit.closeConn(f41);
FTPToolkit.closeConn(f42);
}
}
/**
FTP監聽器 */ class MyFtpListener implements FTPDataTransferListener { private String tag; private MyFtpListener(String tags) {
this.tag = tags;
}
public static MyFtpListener instance(String tags) {
return new MyFtpListener(tags);
}
public void started() {
//System.out.println(tag+ ":FTP啟動。。。。。。");
} public void transferred(int length) {
//System.out.println(tag+ ":FTP傳輸["+length+"]。。。。。。");
} public void completed() {
//System.out.println(tag+ ":FTP完成。。。。。。");
} public void aborted() {
//System.out.println(tag+ ":FTP中止。。。。。。");
} public void failed() {
//System.out.println(tag+ ":FTP掛掉。。。。。。");
} }</pre>