這一期,我們來學習一下如何用Java連接FTP服務器。在工程項目中,我們往往需要連接FTP服務器。當我們有此需求時,可以從兩個方面考慮。第一,根據FTP協議自己寫出一套程序,這是一種思路,當然這是一件很費時又耗成本的一件事。我們是工程師,我們的目的是把需求實現,而不是科研項目。所以得考慮另一種思路,去尋找已經做好的API。好巧,剛好有一個開源組織爲我們做好了這個API,那就是偉大的Apache。下面就開始時根據Apache給我們提供的API完成我們的需求。
第一步,下載jar包,登錄官網如下:
然後找到“Projects”點進去,出現下拉框。點擊“Project List”
找到Commons點進去
往下滑,找到“net”
點進去,然後在左上角找到“download”
點擊然後往下滑,找到如圖
其中Binaries是編譯後的jar,Source是源代碼。一般使用的是編譯後的jar,將其下載,下載之後就是新建項目導jar包。如何導jar,不會再這裏說。此時,我們jar已經準備好。我們還需要一個ftp服務器,如何建立ftp服務器也不會再這裏說。現在假設你已經創建好項目,已經建立好ftp服務器,下面就直接上代碼了。
package my;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
public class TestFTPClient
{
// API裏對中文FTP目錄的處理有點問題
// 在調用 changeWorkingDirectory() / listFiles()等方法時,將參數路徑轉換一下
public static String ftpPath(String path)
{
try
{
return new String(path.getBytes("UTF-8"), FTP.DEFAULT_CONTROL_ENCODING);
} catch (UnsupportedEncodingException e)
{
return "";
}
}
public static void main(String[] args) throws Exception
{
FTPClient ftp = new FTPClient();
// 連接服務器
ftp.connect("127.0.0.1", 21);
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply))
{
ftp.disconnect();
System.out.println("** 無法連接至FTP服務器!");
System.exit(1);
}
if (!ftp.login("test", "123456"))
{
ftp.logout();
System.out.println("** 錯誤的用戶名或密碼!");
System.exit(1);
}
System.out.println("Connected.");
// 字節傳輸 BINARY_FILE_TYPE
// 文本傳輸 ASCII_FILE_TYPE
// 一般使用BINARY模式來傳輸文件,很少使用 ASCII_FILE_TYPE
ftp.setFileType(FTP.BINARY_FILE_TYPE);
// 主動模式: enterLocalActiveMode()
// 被動模式: enterLocalPassiveMode()
// 一般選擇被動模式
ftp.enterLocalPassiveMode();
// 設置控制通道的字符集, 要與服務端的設定一致
ftp.setControlEncoding("UTF-8");
// 切換目錄 ( 用ftpPath() 轉換一下 )
// boolean rc = ftp.changeWorkingDirectory(ftpPath("/圖片"));
// if(!rc)
// {
// System.out.println("切換目錄出錯!");
// }
// ...
//
// 列出所有的文件/子目錄
// listFile(ftp);
//上傳一個文件
//upload(ftp);
// 下載一個文件
download(ftp);
ftp.logout();
ftp.disconnect();
System.out.println("Quit.");
}
public static void listFile(FTPClient ftp)
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("> list");
FTPFile[] ftpFiles;
try
{
ftpFiles = ftp.listFiles();
for (FTPFile f : ftpFiles)
{
String time = sdf.format(f.getTimestamp().getTime());
String info = "";
if (f.isDirectory())
info = String.format("+ %-20s", f.getName());
else
info = String.format(" %-20s %8d %s", f.getName(), f.getSize(), time);
System.out.println(info);
}
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 上傳一個文件
public static void upload(FTPClient ftp)
{
File localFile = new File("E:\\代碼\\HBiuder.zip");
InputStream inStream;
OutputStream outStream;
try
{
String remotePath = ftpPath(localFile.getName());
inStream = new FileInputStream(localFile);
//
// 小文件直接 用
// ftp.storeFile(remotePath, inStream);
//大文件時用這個方法
outStream = ftp.storeFileStream(remotePath);
// 大文件,可以自己掌握進度
byte[] buffer = new byte[4000];
while (true)
{
int n = inStream.read(buffer);
if (n <= 0)
break;
outStream.write(buffer, 0, n);
}
inStream.close();
outStream.close();
} catch (FileNotFoundException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//文件下載
public static void download(FTPClient ftp) throws Exception
{
File localFile = new File("D:/tmp/copy.zip");
localFile.getParentFile().mkdirs();
//
String remotePath = ftpPath("/HBiuder.zip");
OutputStream outStream = new FileOutputStream(localFile);
// 小文件直接 用
// ftp.retrieveFile(remotePath, outStream);
// 大文件,可以自己掌握進度
InputStream inStream = ftp.retrieveFileStream(remotePath);
if(inStream == null)
throw new Exception("遠程文件不存在!" + remotePath);
byte[] buffer = new byte[4000];
while(true)
{
int n =inStream.read(buffer);
if(n <= 0) break;
outStream.write(buffer,0,n);
}
inStream.close();
outStream.close();
}
}
僅供參考,如有不足,多多指教。