**
* 類描述: 檔案斷點續傳工具類
* @author:趙博
* @since:2017-6-14 下午13:41
* @update:[變更日期YYYY-MM-DD][更改人姓名][變更描述]
*
*
*/
public class ContinueFTP2 {
public FTPClient ftpClient = new FTPClient();
private String ftpURL,username,pwd,ftpport,file1,file2;
/******
*
* @param _ftpURL 檔案伺服器長傳位址
* @param _username 使用者名
* @param _pwd 密碼
* @param _ftpport 端口
* @param _file1 要傳輸的檔案
* @param _file2 目的檔案夾
*/
public ContinueFTP2(String _ftpURL,String _username,String _pwd,String _ftpport,String _file1,String _file2 ){
//設定将過程中使用到的指令輸出到控制台
ftpURL = _ftpURL;
username = _username;
pwd = _pwd;
ftpport = _ftpport;
file1 = _file1;
file2 = _file2;
ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
}
/**
* 連接配接到FTP伺服器
* @param hostname 主機名
* @param port 端口
* @param username 使用者名
* @param password 密碼
* @return 是否連接配接成功
* @throws IOException
*/
public boolean connect(String hostname,int port,String username,String password) throws IOException{
ftpClient.connect(hostname, port);
ftpClient.setControlEncoding("GBK");
if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){
if(ftpClient.login(username, password)){
return true;
}
}
disconnect();
return false;
}
/** *//**
* 斷開與遠端伺服器的連接配接
* @throws IOException
*/
public void disconnect() throws IOException{
if(ftpClient.isConnected()){
ftpClient.disconnect();
}
}
/** *//**
* 遞歸建立遠端伺服器目錄
* @param remote 遠端伺服器檔案絕對路徑
* @param ftpClient FTPClient 對象
* @return 目錄建立是否成功
* @throws IOException
*/
public UploadStatus CreateDirecroty(String remote,FTPClient ftpClient) throws IOException{
UploadStatus status = UploadStatus.Create_Directory_Success;
String directory = remote.substring(0,remote.lastIndexOf("/")+1);
if(!directory.equalsIgnoreCase("/")&&!ftpClient.changeWorkingDirectory(new String(directory.getBytes("GBK"),"iso-8859-1"))){
//如果遠端目錄不存在,則遞歸建立遠端伺服器目錄
int start=0;
int end = 0;
if(directory.startsWith("/")){
start = 1;
}else{
start = 0;
}
end = directory.indexOf("/",start);
while(true){
String subDirectory = new String(remote.substring(start,end).getBytes("GBK"),"iso-8859-1");
if(!ftpClient.changeWorkingDirectory(subDirectory)){
if(ftpClient.makeDirectory(subDirectory)){
ftpClient.changeWorkingDirectory(subDirectory);
}else {
System.out.println("建立目錄失敗");
return UploadStatus.Create_Directory_Fail;
}
}
start = end + 1;
end = directory.indexOf("/",start);
//檢查所有目錄是否建立完畢
if(end <= start){
break;
}
}
}
return status;
}
/** *//**
* 上傳檔案到伺服器,新上傳和斷點續傳
* @param remoteFile 遠端檔案名,在上傳之前已經将伺服器工作目錄做了改變
* @param localFile 本地檔案 File句柄,絕對路徑
* @param processStep 需要顯示的處理進度步進值
* @param ftpClient FTPClient 引用
* @return
* @throws IOException
*/
public UploadStatus uploadFile(String remoteFile,File localFile,FTPClient ftpClient,long remoteSize) throws IOException{
UploadStatus status;
//顯示進度的上傳
long step = localFile.length() / 100;
long process = 0;
long localreadbytes = 0L;
RandomAccessFile raf = new RandomAccessFile(localFile,"r");
OutputStream out = ftpClient.appendFileStream(new String(remoteFile.getBytes("GBK"),"iso-8859-1"));
//斷點續傳
if(remoteSize>0){
ftpClient.setRestartOffset(remoteSize);
process = remoteSize /step;
raf.seek(remoteSize);
localreadbytes = remoteSize;
}
byte[] bytes = new byte[1024];
int c;
while((c = raf.read(bytes))!= -1){
out.write(bytes,0,c);
localreadbytes+=c;
if(localreadbytes / step != process){
process = localreadbytes / step;
System.out.println("上傳進度:" + process);
//TODO 彙報上傳狀态
}
}
out.flush();
raf.close();
out.close();
boolean result =ftpClient.completePendingCommand();
if(remoteSize > 0){
status = result?UploadStatus.Upload_From_Break_Success:UploadStatus.Upload_From_Break_Failed;
}else {
status = result?UploadStatus.Upload_New_File_Success:UploadStatus.Upload_New_File_Failed;
}
return status;
}
public void downloadFile(String remote,String local){
try{
FTPFile[] filelist=ftpClient.listFiles(remote);
FTPFile ftpFile = null;
String category = null;
int length = filelist.length;
for (int i = 0; i < length; i++) {
ftpFile = filelist[i];
category = ftpFile.getName();
if(ftpFile.isFile()){
download(remote+category, local+category);
}else{
String wjj=local+category;
File file=new File(wjj);
if(file.exists()){
downloadFile(remote+category+"//", local+category+"\\");
}else{
if(file.mkdir()){
downloadFile(remote+category+"//", local+category+"\\");
}
}
}
}
}catch(Exception e){
System.out.println(e.getMessage());
}
}
/** *//**
* 從FTP伺服器上下載下傳檔案,支援斷點續傳,上傳百分比彙報
* @param remote 遠端檔案路徑
* @param local 本地檔案路徑
* @return 上傳的狀态
* @throws IOException
*/
public DownloadStatus download(String remote,String local) throws IOException{
//設定被動模式
ftpClient.enterLocalPassiveMode();
//設定以二進制方式傳輸
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
DownloadStatus result;
//檢查遠端檔案是否存在
FTPFile[] files = ftpClient.listFiles(new String(remote.getBytes("GBK"),"iso-8859-1"));
if(files.length != 1){
System.out.println("遠端檔案不存在");
return DownloadStatus.Remote_File_Noexist;
}
long lRemoteSize = files[0].getSize();
File f = new File(local);
//本地存在檔案,進行斷點下載下傳
if(f.exists()){
long localSize = f.length();
//判斷本地檔案大小是否大于遠端檔案大小
if(localSize >= lRemoteSize){
System.out.println("本地檔案大于遠端檔案,下載下傳中止");
return DownloadStatus.Local_Bigger_Remote;
}
//進行斷點續傳,并記錄狀态
FileOutputStream out = new FileOutputStream(f,true);
ftpClient.setRestartOffset(localSize);
InputStream in = ftpClient.retrieveFileStream(new String(remote.getBytes("GBK"),"iso-8859-1"));
byte[] bytes = new byte[1024];
long step = lRemoteSize /100;
long process=localSize /step;
int c;
while((c = in.read(bytes))!= -1){
out.write(bytes,0,c);
localSize+=c;
long nowProcess = localSize /step;
if(nowProcess > process){
process = nowProcess;
if(process % 10 == 0)
System.out.println("下載下傳進度:"+process);
//TODO 更新檔案下載下傳進度,值存放在process變量中
}
}
in.close();
out.close();
boolean isDo = ftpClient.completePendingCommand();
if(isDo){
result = DownloadStatus.Download_From_Break_Success;
}else {
result = DownloadStatus.Download_From_Break_Failed;
}
}else {
OutputStream out = new FileOutputStream(f);
InputStream in= ftpClient.retrieveFileStream(new String(remote.getBytes("GBK"),"iso-8859-1"));
byte[] bytes = new byte[1024];
long step = lRemoteSize /100;
long process=0;
long localSize = 0L;
int c;
while((c = in.read(bytes))!= -1){
out.write(bytes, 0, c);
localSize+=c;
long nowProcess = localSize /step;
if(nowProcess > process){
process = nowProcess;
if(process % 10 == 0)
System.out.println("下載下傳進度:"+process);
//TODO 更新檔案下載下傳進度,值存放在process變量中
}
}
in.close();
out.close();
boolean upNewStatus = ftpClient.completePendingCommand();
if(upNewStatus){
result = DownloadStatus.Download_New_Success;
}else {
result = DownloadStatus.Download_New_Failed;
}
}
return result;
}
public void moveFTPFile(FTPClient ftpClient, String from, String to){
boolean result=true;
try {
FTPFile[] filelist=ftpClient.listFiles(from);
FTPFile ftpFile = null;
String category = null;
int length = filelist.length;
for (int i = 0; i < length; i++) {
ftpFile = filelist[i];
category = ftpFile.getName();
if (ftpFile.isFile()) {
ftpClient.rename(from+category, to+category);
}else{
ftpClient.rename(from+category, to+category);
//moveFTPFile(ftpClient,from+category+"//",to+"//");
}
}
} catch (IOException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
}
public boolean copyFTPFile(FTPClient ftpClient, String from, String to){
boolean copyFalg = false;
FTPFile[] filelist;
try {
// 枚舉目前from目錄所有檔案+子目錄
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
filelist = ftpClient.listFiles(from);
int length = filelist.length;
FTPFile ftpFile = null;
String category = null;
InputStream inputStream = null;
for (int i = 0; i < length; i++) {
ftpFile = filelist[i];
category = ftpFile.getName();
if (ftpFile.isFile()) {
ftpClient.setBufferSize(1024);
ByteArrayOutputStream fos=new ByteArrayOutputStream();
ftpClient.retrieveFile(from, fos);
ByteArrayInputStream in=new ByteArrayInputStream(fos.toByteArray());
ftpClient.storeFile(to, in);
fos.close();
in.close();
} else if (ftpFile.isDirectory()) {
// 如果是目錄則先建立該目錄
// copyFalg = ftpClient.makeDirectory(to);
// 再進入子目錄進行遞歸複制
//copyDirectory(ftpClient, from , to);
}
}
} catch (IOException e) {
// logger.error("FtpClientUtil.copyDirectory failed. caused by " + e.getMessage(), e);
copyFalg = false;
}
return copyFalg;
}
public boolean delete(FTPClient ftpClient,String deltefile){
try {
ftpClient.deleteFile(deltefile);
} catch (IOException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
return true;
}
public static void main(String args[]){
try {
ContinueFTP2 ftp=new ContinueFTP2("192.168.7.24", "username", "password", "21", null, null);
boolean isconnect=ftp.connect("192.168.7.24", 21, "username", "password");
String from="//CloudStation//web-tps-file//pinncal//pending//";
String to="//CloudStation//web-tps-file//pinncal//alreadyDeal//";
String resulttpssb="//CloudStation//web-tps-file//pinncal//result//deal-fail//";
String resulttpscg="//CloudStation//web-tps-file//pinncal//result//deal-succeed//";
String tbcg="E:\\資訊中心研發部\\開發項目文檔\\架構設計文檔\\網頁自動計劃\\雲端TPS檔案區域\\result\\deal-succeed\\";
String tbsb="E:\\資訊中心研發部\\開發項目文檔\\架構設計文檔\\網頁自動計劃\\雲端TPS檔案區域\\result\\deal-fail\\";
if(isconnect){
long remotesize=1024L;
ftp.downloadFile(resulttpssb,tbsb);
//ftp.moveFTPFile(ftp.ftpClient, from, from, to);
ftp.downloadFile(resulttpscg,tbcg);
//ftp.moveFTPFile(ftp.ftpClient, from, to);
//ftp.copyFTPFile(ftp.ftpClient, from,to);
// ftp.delete(ftp.ftpClient, from);
//ftp.uploadFile("//CloudStation//web-tps-file//pinncal//1.xlsx", new File("C:\\Users\\Allcure\\Downloads\\1.xlsx"), ftp.ftpClient, remotesize);
}
} catch (IOException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
}