當前位置:首頁 » 文件傳輸 » ftpclient被動模式
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

ftpclient被動模式

發布時間: 2022-07-27 17:43:31

1. java 實現ftp上傳下載,windows下和linux下游何區別

packagecom.weixin.util;

importjava.io.File;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.OutputStream;
importjava.io.PrintWriter;
importjava.io.RandomAccessFile;

importorg.apache.commons.net.PrintCommandListener;
importorg.apache.commons.net.ftp.FTP;
importorg.apache.commons.net.ftp.FTPClient;
importorg.apache.commons.net.ftp.FTPFile;
importorg.apache.commons.net.ftp.FTPReply;

importcom.weixin.constant.DownloadStatus;
importcom.weixin.constant.UploadStatus;

/**
*支持斷點續傳的FTP實用類
*@version0.1實現基本斷點上傳下載
*@version0.2實現上傳下載進度匯報
*@version0.3實現中文目錄創建及中文文件創建,添加對於中文的支持
*/
publicclassContinueFTP{
publicFTPClientftpClient=newFTPClient();

publicContinueFTP(){
//設置將過程中使用到的命令輸出到控制台
this.ftpClient.addProtocolCommandListener(newPrintCommandListener(newPrintWriter(System.out)));
}

/**
*連接到FTP伺服器
*@paramhostname主機名
*@paramport埠
*@paramusername用戶名
*@parampassword密碼
*@return是否連接成功
*@throwsIOException
*/
publicbooleanconnect(Stringhostname,intport,Stringusername,Stringpassword)throwsIOException{
ftpClient.connect(hostname,port);
ftpClient.setControlEncoding("GBK");
if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){
if(ftpClient.login(username,password)){
returntrue;
}
}
disconnect();
returnfalse;
}

/**
*從FTP伺服器上下載文件,支持斷點續傳,上傳百分比匯報
*@paramremote遠程文件路徑
*@paramlocal本地文件路徑
*@return上傳的狀態
*@throwsIOException
*/
publicDownloadStatusdownload(Stringremote,Stringlocal)throwsIOException{
//設置被動模式
ftpClient.enterLocalPassiveMode();
//設置以二進制方式傳輸
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
DownloadStatusresult;

//檢查遠程文件是否存在
FTPFile[]files=ftpClient.listFiles(newString(remote.getBytes("GBK"),"iso-8859-1"));
if(files.length!=1){
System.out.println("遠程文件不存在");
returnDownloadStatus.Remote_File_Noexist;
}

longlRemoteSize=files[0].getSize();
Filef=newFile(local);
//本地存在文件,進行斷點下載
if(f.exists()){
longlocalSize=f.length();
//判斷本地文件大小是否大於遠程文件大小
if(localSize>=lRemoteSize){
System.out.println("本地文件大於遠程文件,下載中止");
returnDownloadStatus.Local_Bigger_Remote;
}

//進行斷點續傳,並記錄狀態
FileOutputStreamout=newFileOutputStream(f,true);
ftpClient.setRestartOffset(localSize);
InputStreamin=ftpClient.retrieveFileStream(newString(remote.getBytes("GBK"),"iso-8859-1"));
byte[]bytes=newbyte[1024];
longstep=lRemoteSize/100;
longprocess=localSize/step;
intc;
while((c=in.read(bytes))!=-1){
out.write(bytes,0,c);
localSize+=c;
longnowProcess=localSize/step;
if(nowProcess>process){
process=nowProcess;
if(process%10==0)
System.out.println("下載進度:"+process);
//TODO更新文件下載進度,值存放在process變數中
}
}
in.close();
out.close();
booleanisDo=ftpClient.completePendingCommand();
if(isDo){
result=DownloadStatus.Download_From_Break_Success;
}else{
result=DownloadStatus.Download_From_Break_Failed;
}
}else{
OutputStreamout=newFileOutputStream(f);
InputStreamin=ftpClient.retrieveFileStream(newString(remote.getBytes("GBK"),"iso-8859-1"));
byte[]bytes=newbyte[1024];
longstep=lRemoteSize/100;
longprocess=0;
longlocalSize=0L;
intc;
while((c=in.read(bytes))!=-1){
out.write(bytes,0,c);
localSize+=c;
longnowProcess=localSize/step;
if(nowProcess>process){
process=nowProcess;
if(process%10==0)
System.out.println("下載進度:"+process);
//TODO更新文件下載進度,值存放在process變數中
}
}
in.close();
out.close();
booleanupNewStatus=ftpClient.completePendingCommand();
if(upNewStatus){
result=DownloadStatus.Download_New_Success;
}else{
result=DownloadStatus.Download_New_Failed;
}
}
returnresult;
}

/**
*上傳文件到FTP伺服器,支持斷點續傳
*@paramlocal本地文件名稱,絕對路徑
*@paramremote遠程文件路徑,使用/home/directory1/subdirectory/file.ext按照Linux上的路徑指定方式,支持多級目錄嵌套,支持遞歸創建不存在的目錄結構
*@return上傳結果
*@throwsIOException
*/
publicUploadStatusupload(Stringlocal,Stringremote)throwsIOException{
//設置PassiveMode傳輸
ftpClient.enterLocalPassiveMode();
//設置以二進制流的方式傳輸
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.setControlEncoding("GBK");
UploadStatusresult;
//對遠程目錄的處理
StringremoteFileName=remote;
if(remote.contains("/")){
remoteFileName=remote.substring(remote.lastIndexOf("/")+1);
//創建伺服器遠程目錄結構,創建失敗直接返回
if(CreateDirecroty(remote,ftpClient)==UploadStatus.Create_Directory_Fail){
returnUploadStatus.Create_Directory_Fail;
}
}

//檢查遠程是否存在文件
FTPFile[]files=ftpClient.listFiles(newString(remoteFileName.getBytes("GBK"),"iso-8859-1"));
if(files.length==1){
longremoteSize=files[0].getSize();
Filef=newFile(local);
longlocalSize=f.length();
if(remoteSize==localSize){
returnUploadStatus.File_Exits;
}elseif(remoteSize>localSize){
returnUploadStatus.Remote_Bigger_Local;
}

//嘗試移動文件內讀取指針,實現斷點續傳
result=uploadFile(remoteFileName,f,ftpClient,remoteSize);

//如果斷點續傳沒有成功,則刪除伺服器上文件,重新上傳
if(result==UploadStatus.Upload_From_Break_Failed){
if(!ftpClient.deleteFile(remoteFileName)){
returnUploadStatus.Delete_Remote_Faild;
}
result=uploadFile(remoteFileName,f,ftpClient,0);
}
}else{
result=uploadFile(remoteFileName,newFile(local),ftpClient,0);
}
returnresult;
}
/**
*斷開與遠程伺服器的連接
*@throwsIOException
*/
publicvoiddisconnect()throwsIOException{
if(ftpClient.isConnected()){
ftpClient.disconnect();
}
}

/**
*遞歸創建遠程伺服器目錄
*@paramremote遠程伺服器文件絕對路徑
*@paramftpClientFTPClient對象
*@return目錄創建是否成功
*@throwsIOException
*/
(Stringremote,FTPClientftpClient)throwsIOException{
UploadStatusstatus=UploadStatus.Create_Directory_Success;
Stringdirectory=remote.substring(0,remote.lastIndexOf("/")+1);
if(!directory.equalsIgnoreCase("/")&&!ftpClient.changeWorkingDirectory(newString(directory.getBytes("GBK"),"iso-8859-1"))){
//如果遠程目錄不存在,則遞歸創建遠程伺服器目錄
intstart=0;
intend=0;
if(directory.startsWith("/")){
start=1;
}else{
start=0;
}
end=directory.indexOf("/",start);
while(true){
StringsubDirectory=newString(remote.substring(start,end).getBytes("GBK"),"iso-8859-1");
if(!ftpClient.changeWorkingDirectory(subDirectory)){
if(ftpClient.makeDirectory(subDirectory)){
ftpClient.changeWorkingDirectory(subDirectory);
}else{
System.out.println("創建目錄失敗");
returnUploadStatus.Create_Directory_Fail;
}
}

start=end+1;
end=directory.indexOf("/",start);

//檢查所有目錄是否創建完畢
if(end<=start){
break;
}
}
}
returnstatus;
}

/**
*上傳文件到伺服器,新上傳和斷點續傳
*@paramremoteFile遠程文件名,在上傳之前已經將伺服器工作目錄做了改變
*@paramlocalFile本地文件File句柄,絕對路徑
*@paramprocessStep需要顯示的處理進度步進值
*@paramftpClientFTPClient引用
*@return
*@throwsIOException
*/
publicUploadStatusuploadFile(StringremoteFile,FilelocalFile,FTPClientftpClient,longremoteSize)throwsIOException{
UploadStatusstatus;
//顯示進度的上傳
longstep=localFile.length()/100;
longprocess=0;
longlocalreadbytes=0L;
RandomAccessFileraf=newRandomAccessFile(localFile,"r");
OutputStreamout=ftpClient.appendFileStream(newString(remoteFile.getBytes("GBK"),"iso-8859-1"));
//斷點續傳
if(remoteSize>0){
ftpClient.setRestartOffset(remoteSize);
process=remoteSize/step;
raf.seek(remoteSize);
localreadbytes=remoteSize;
}
byte[]bytes=newbyte[1024];
intc;
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();
booleanresult=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;
}
returnstatus;
}

publicstaticvoidmain(String[]args){
ContinueFTPmyFtp=newContinueFTP();
try{
System.err.println(myFtp.connect("10.10.6.236",21,"5","jieyan"));
// myFtp.ftpClient.makeDirectory(newString("歌曲".getBytes("GBK"),"iso-8859-1"));
// myFtp.ftpClient.changeWorkingDirectory(newString("歌曲".getBytes("GBK"),"iso-8859-1"));
// myFtp.ftpClient.makeDirectory(newString("愛你等於愛自己".getBytes("GBK"),"iso-8859-1"));
// System.out.println(myFtp.upload("E:\yw.flv","/yw.flv",5));
// System.out.println(myFtp.upload("E:\愛你等於愛自己.mp4","/愛你等於愛自己.mp4"));
//System.out.println(myFtp.download("/愛你等於愛自己.mp4","E:\愛你等於愛自己.mp4"));
myFtp.disconnect();
}catch(IOExceptione){
System.out.println("連接FTP出錯:"+e.getMessage());
}
}
}

2. FTPClient.storeFile報連接超時。但是已經能login,而且建立了文件夾了。再調storeFile時報錯。

我遇到過這個問題,改成在建立連接之前設置被動模式,就可以上傳了。

3. FTP協議有兩種工作方式是什麼

Ftp協議的兩種工作模式:主動模式active和被動模式passive



FTP 是一種數據傳輸協議 (File Transfer Protocol),它的連接模式有兩種: 主動模式( active )和被動模式( passive )。



以下說明FTP的連接是怎樣建立的:



在 active 模式下 (一般預設的模式):



FTP client 開啟一個隨機選擇的TCP port 呼叫 FTP server 的 port 21請求建立連接。當完成 Three-Way Handshake 之後,連接就成功建立,但這僅是命令通道的建立。

當兩端需要傳送數據資料的時候,client 透過命令通道用一個 port command 告訴 server ,client可以用另一個TCP port 做數據通道。

然後 server 用 port 20 和剛才client 所告知的 TCP port 建立數據連接。注意:連接方向是從server 到 client 的,TCP 分組中會有一個 SYN flag。

然後 client 會返回一個帶 ACK flag的確認分組,並完成另一次的 Three-Way Handshake 過程。這時候,數據連接才能成功建立。開始數據傳送。



在 passive 模式下:



FTP client 開啟一個隨機選擇的TCP port 呼叫 FTP server 的 port 21請求建立連接,完成命令通道的建立。

當兩端需要傳送數據的時候,client 通過命令通道發送一個 PASV command 給server,要求進入 passive 傳輸模式。

然後 server 像上述的正常模式之第 2 步驟那樣,挑一個TCP port ,並用命令通道告訴 client。

然後 client 用另一個TCP port 呼叫剛才 server 告知的 TCP port 來建立數據通道。此時分組中帶有 SYN flag。

server 確認後回送一個 ACK 分組。並完成所有握手過程、成功建立數據通道。

開始數據傳送。 在實際使用中, active mode 用來登入一些架設在主機上沒有安裝防火牆的 FTP server,或是架設在 client side 的 FTP server! Passive mode (簡稱 PASV)用來登陸一些架設於防火牆保護下而又是開設於主機上的 FTP server!

4. 關於FTP 映射的問題,涉及主動,被動模式

如果是私網client訪問公網ftp server,在主動模式下,需要防火牆/路由器開啟ALG(application layer gateway)功能,功能開啟後路由器/防火牆會從ftp控制報文中提取通訊埠信息,然後事先在防火牆/路由器將通訊埠映射。
你所說的情況是ftp server在私網,不知道情況是不是類似。

5. java里使用ftpClient的被動方式訪問ftp伺服器讀取一系列文件夾,只有第一個內容能讀到,其他讀不到

你basePath應該有問題,basePath應該指向要刪除目錄的上一級目錄.

6. ubuntu和centos,centos上用vsftp搭建FTP伺服器,windows上用FileZilla Client主被動模式都可以正常訪問

將你的FTP軟體的工作模式設置為 pasv模式 就OK了 軟體不同設置方法不同
(1)IE:工具 -> Internet選項 -> 高級 -> 「使用被動FTP」(需要IE6.0以上才支持)。
(2)CuteFTP:Edit -> Setting -> Connection -> Firewall -> 「PASV Mode」 或File -> Site Manager,在左邊選中站點 -> Edit -> 「Use PASV mode」 。
(3)FlashGet:工具 -> 選項 -> 代理伺服器 -> 直接連接 -> 編輯 -> 「PASV模式」。
(4)FlashFXP:選項 -> 參數選擇 -> 代理/防火牆/標識 -> 「使用被動模式」 或 站點管理 -> 對應站點 -> 選項 -> 「使用被動模式」或快速連接 -> 切換 -> 「使用被動模式」。

在cmd裡面:
如果需要切換到PORT模式:quote PORT;
同樣,如果需要PASV模式:quote PASV即可.

7. ftp的路徑怎麼設置

你先使用cd 命令切換到你想下載的目錄下,如:
cmd
cd d:\wenjian

之後在使用ftp命令。就可以了

8. java的ftp用匿名如何登陸啊...下載中文亂碼......

首先,匿名不是null,匿名是anonymous,密碼可以為空

亂碼
ftpConfig.setServerLanguageCode("zh");

ftpClient.setControlEncoding("GBK");

如果還為亂碼,則加上轉碼
new String(names[i].getBytes("GBK"),"ISO-8859-1")

9. 為什麼ftp用FileZilla可以正常上傳圖片,使用java代碼走到client.storefile();就

既然你可以用filezilla連接並實現上傳, 說明伺服器是沒有問題的, 那麼就要檢查一下你的windows是否有問題了. 首先看一下windows的防火牆是不是開了, 如果打開了, 關閉一下, 再嘗試一下上傳功能, 看能夠成功. 如果不行, 看一下你的ftpclient相關的jar包版本和jdk版本是否匹配, 這里也可能出問題.
希望能夠幫到你.