進口?Java . io . file;
進口?Java . io . file output stream;
進口?Java . io . io exception;
進口?Java . io . inputstream;
進口?Java . io . output stream;
進口?Java . io . printwriter;
進口?Java . io . random access file;
進口?org . Apache . commons . net . print command listener;
進口?org . Apache . commons . net . FTP . FTP;
進口?org . Apache . commons . net . FTP . FTP client;
進口?org . Apache . commons . net . FTP . FTP file;
進口?org . Apache . commons . net . FTP . FTP preply;
進口?com . weixin . constant . download status;
進口?com . weixin . constant . upload status;
/**
*?支持斷點續傳的FTP實用程序類
*?@版本?0.1?實現基本斷點的上傳和下載
*?@版本?0.2?實現上傳和下載進度報告
*?@版本?0.3?實現中文目錄和中文文件的創建,並增加對中文的支持。
*/
公共?班級?ContinueFTP?{
公共?FTPClient?ftpClient?=?新的?FTP client();
公共?ContinueFTP(){
//設置將進程中使用的命令輸出到控制臺。
this . FTP client . addprotocolcommandlistener(新?PrintCommandListener(新?PrintWriter(system . out)));
}
/**
?*?連接到FTP服務器
?*?@param?主機名?主機名
?*?@param?港口?港口
?*?@param?用戶名?用戶名
?*?@param?密碼?密碼
?*?@回歸?連接成功嗎?
?*?@throws?IOException
?*/
公共?布爾?連接(字符串?主機名,int?端口,字符串?用戶名,字符串?密碼)?摔投?IOException{
ftpClient.connect(主機名,港口);
FTP client . setcontrolencoding(" GBK ");
if(FTP preply . ispositivecompletion(FTP client . getreplycode()){
if(ftpClient.login(用戶名,密碼)){
回歸?真實;
}
}
disconnect();
回歸?假的;
}
/**
?*?從FTP服務器下載文件,支持斷點續傳和上傳百分比報告。
?*?@param?遠程?遠程文件路徑
?*?@param?本地的?本地文件路徑
?*?@回歸?上傳狀態
?*?@throws?IOException
?*/
公共?DownloadStatus?下載(字符串?遠程,字符串?本地)?摔投?IOException{
//設置被動模式
FTP client . enterlocalpassivemode();
//以二進制模式設置傳輸
ftpClient.setFileType(FTP。BINARY _ FILE _ TYPE);
DownloadStatus?結果;
//檢查遠程文件是否存在。
FTPFile[]?文件?=?ftpClient.listFiles(新?String(remote.getBytes("GBK ")," iso-8859-1 "));
if(files.length?!=?1){
System.out.println("遠程文件不存在");
回歸?下載狀態。遠程文件不存在;
}
龍?lRemoteSize?=?文件[0]。getSize();
文件?f?=?新的?文件(本地);
//文件在本地,斷點下載。
if(f.exists()){
龍?localSize?=?f . length();
//判斷本地文件大小是否大於遠程文件大小。
if(localSize?& gt=?lRemoteSize){
System.out.println("本地文件大於遠程文件,下載中止");
回歸?下載狀態。本地_更大_遠程;
}
//恢復斷點並記錄狀態。
FileOutputStream?出局?=?新的?FileOutputStream(f,true);
FTP client . setrestartoffset(localSize);
InputStream?在?=?ftpClient.retrieveFileStream(新?String(remote.getBytes("GBK ")," iso-8859-1 "));
byte[]?字節?=?新的?byte[1024];
龍?壹步?=?lRemoteSize?/100;
龍?process=localSize?/step;
int?c;
而((c?=?in.read(字節))!=?-1){
out.write(bytes,0,c);
localSize+= c;
龍?現在流程?=?localSize?/step;
if(nowProcess?& gt?流程){
流程?=?nowProcess
如果(流程?%?10?==?0)
System.out.println("下載進度:"+process);
//TODO?更新文件下載進度,值存儲在流程變量中。
}
}
in . close();
out . close();
布爾?isDo?=?FTP client . completependingcommand();
if(isDo){
結果?=?下載狀態。下載_ From _ Break _ Success
}別的?{
結果?=?下載狀態。下載失敗;
}
}別的?{
OutputStream?出局?=?新的?file output stream(f);
InputStream?in=?ftpClient.retrieveFileStream(新?String(remote.getBytes("GBK ")," iso-8859-1 "));
byte[]?字節?=?新的?byte[1024];
龍?壹步?=?lRemoteSize?/100;
龍?進程= 0;
龍?localSize?=?0L;
int?c;
而((c?=?in.read(字節))!=?-1){
out.write(字節,?0,?c);
localSize+= c;
龍?現在流程?=?localSize?/step;
if(nowProcess?& gt?流程){
流程?=?nowProcess
如果(流程?%?10?==?0)
System.out.println("下載進度:"+process);
//TODO?更新文件下載進度,值存儲在流程變量中。
}
}
in . close();
out . close();
布爾?upNewStatus?=?FTP client . completependingcommand();
if(upNewStatus){
結果?=?下載狀態。下載_新建_成功;
}別的?{
結果?=?下載狀態。下載_新建_失敗;
}
}
回歸?結果;
}
/**
?*?上傳文件到FTP服務器,支持斷點續傳。
?*?@param?本地的?本地文件名,絕對路徑
?*?@param?遠程?遠程文件路徑,使用/home/directory 1/子目錄/file.ext?根據Linux上的路徑指定方法,支持多級目錄嵌套和遞歸創建不存在的目錄結構。
?*?@回歸?上傳結果
?*?@throws?IOException
?*/
公共?UploadStatus?上傳(字符串?本地,字符串?遠程)?摔投?IOException{
//設置PassiveMode傳輸
FTP client . enterlocalpassivemode();
//將傳輸設置為二進制流。
ftpClient.setFileType(FTP。BINARY _ FILE _ TYPE);
FTP client . setcontrolencoding(" GBK ");
UploadStatus?結果;
//遠程目錄的處理
字符串?遠程文件名?=?遠程;
if(remote . contains("/"){
遠程文件名?=?remote . substring(remote . lastindexof("/"+1);
//創建服務器的遠程目錄結構,創建失敗直接返回。
if(CreateDirecroty(remote,?ftpClient)==UploadStatus。創建目錄失敗){
回歸?上傳狀態。創建目錄失敗;
}
}
//檢查文件是否遠程存在。
FTPFile[]?文件?=?ftpClient.listFiles(新?string(remote filename . getbytes(" GBK ")," iso-8859-1 "));
if(files.length?==?1){
龍?remoteSize?=?文件[0]。getSize();
文件?f?=?新的?文件(本地);
龍?localSize?=?f . length();
if(remoteSize==localSize){
回歸?上傳狀態。文件_出口;
}別的?if(remoteSize?& gt?localSize){
回歸?上傳狀態。遠程_更大_本地;
}
//嘗試在文件中移動讀取指針,實現斷點續傳。
結果?=?上傳文件(遠程文件名,f,?ftpClient,?remoteSize);
//如果斷點續傳不成功,刪除服務器上的文件,重新上傳。
如果(結果?==?上傳狀態。上傳_自_中斷_失敗){
如果(!FTP client . delete file(remote filename)){
回歸?上傳狀態。刪除遠程失敗;
}
結果?=?上傳文件(遠程文件名,f,?ftpClient,?0);
}
}別的?{
結果?=?上傳文件(遠程文件名,新的?文件(本地),?ftpClient,?0);
}
回歸?結果;
}
/**
?*?斷開與遠程服務器的連接。
?*?@throws?IOException
?*/
公共?作廢?斷開()?摔投?IOException{
if(ftpClient.isConnected()){
FTP client . disconnect();
}
}
/**
?*?遞歸創建遠程服務器目錄
?*?@param?遠程?遠程服務器文件的絕對路徑
?*?@param?ftpClient?FTPClient對象
?*?@回歸?目錄創建是否成功?
?*?@throws?IOException
?*/
公共?UploadStatus?CreateDirecroty(字符串?遠程,FTP客戶端?ftpClient)?摔投?IOException{
UploadStatus?地位?=?上傳狀態。創建_目錄_成功;
字符串?目錄?=?remote.substring(0,remote . lastindexof("/")+1);
如果(!directory . equalsignorecase("/" & amp;& amp!FTP client . changeworking directory(新?String(directory.getBytes("GBK ")," iso-8859-1 ")){
//如果遠程目錄不存在,遞歸創建遠程服務器目錄。
int?start = 0;
int?結束?=?0;
if(directory . starts with("/"){
開始?=?1;
}否則{
開始?=?0;
}
結束?=?directory.indexOf("/",start);
while(true){
字符串?子目錄?=?新的?String(remote.substring(start,end))。getBytes(“GBK”),“iso-8859-1”);
如果(!FTP client . changeworking directory(子目錄)){
if(ftpClient.makeDirectory(子目錄)){
FTP client . changeworkingdirectory(子目錄);
}別的?{
System.out.println("未能創建目錄");
回歸?上傳狀態。創建目錄失敗;
}
}
開始?=?結束?+?1;
結束?=?directory.indexOf("/",start);
//檢查是否已經創建了所有目錄。
如果(結束?& lt=?開始){
打破;
}
}
}
回歸?地位;
}
/**
?*?上傳文件到服務器,新的上傳和斷點續傳。
?*?@param?遠程文件?遠程文件名,上傳前服務器工作目錄已更改。
?*?@param?本地文件?本地文件的句柄文件,絕對路徑
?*?@param?processStep?要顯示的處理進度步驟值
?*?@param?ftpClient?FTP客戶端參考
?*?@返回
?*?@throws?IOException
?*/
公共?UploadStatus?uploadFile(字符串?遠程文件,文件?localFile,FTPClient?ftpClient,long?remoteSize)?摔投?IOException{
UploadStatus?地位;
//顯示上傳進度。
龍?壹步?=?localFile.length()。/?100;
龍?流程?=?0;
龍?localreadbytes?=?0L;
RandomAccessFile?皇家空軍?=?新的?RandomAccessFile(localFile," r ");
OutputStream?出局?=?ftpClient.appendFileStream(新?string(remote file . getbytes(" GBK ")," iso-8859-1 "));
//斷點續傳
if(remoteSize & gt;0){
FTP client . setrestartoffset(remoteSize);
流程?=?remoteSize?/step;
RAF . seek(remoteSize);
localreadbytes?=?remoteSize
}
byte[]?字節?=?新的?byte[1024];
int?c;
而((c?=?raf.read(字節))。=?-1){
out.write(bytes,0,c);
localreadbytes+= c;
if(localreadbytes?/?壹步?!=?流程){
流程?=?localreadbytes?/?步;
System.out.println("上傳進度:"?+?流程);
//TODO?報告上傳狀態
}
}
out . flush();
RAF . close();
out . close();
布爾?結果?= FTP client . completependingcommand();
if(remoteSize?& gt?0){
地位?=?結果?上傳狀態。Upload_From_Break_Success:上傳狀態。Upload _ From _ Break _失敗;
}別的?{
地位?=?結果?上傳狀態。上傳_新_文件_成功:上傳狀態。上傳新文件失敗;
}
回歸?地位;
}
公共?靜電?作廢?main(String[]?args)?{
ContinueFTP?myFtp?=?新的?continue FTP();
試試?{
system . err . println(my FTP . connect(" 10.10.6 . 236 ",21,?"5",?“燕傑”));
//my FTP . FTP client . make directory(新?弦(“宋”。getbytes ("GBK ")," ISO-8859-1 "));
//my FTP . FTP client . changeworkingdirectory(new?弦(“宋”。getbytes ("GBK ")," ISO-8859-1 "));
//my FTP . FTP client . make directory(新?String(“愛妳等於愛自己”。getbytes(“GBK”),“ISO-8859-1”);
//system . out . println(my FTP . upload(" E:\ \ yw . flv ",?"/yw.flv ",5));
//系統。out.println (myftp.upload ("e: \ \愛妳等於愛自己. mp4 ","/愛妳等於愛自己. MP4 "));
//系統。out . println(my FTP . download("/愛妳等於愛自己. mp4 ",“E:\\愛妳等於愛自己。MP4”);
myftp . disconnect();
}?接住?(IOException?e)?{
System.out.println("連接FTP時出錯:"+e . getmessage());
}
}
}