記錄一次對FTP服務器文件內容
通過Java程序對FTP服務器文件處理:連接,上傳,下載,讀取,移動文件等。
需求描述:今天接到一個任務,在Java項目中,讀取FTP服務器上的一些文件,進行一些業務操作。處理完之后,將讀取過的文件移動到其他目錄里面。這就是我需求。
記錄一下使用過程:這里使用的是 org.apache.commons.net.ftp.FTP 這個FTP處理包。
碰到的幾個你可能看這篇文章要解決的碰到的問題,提前說下解決方案:
-
完全不知道FTP的API如何使用,無從下手?(直接看方法就行了,很簡單)
-
訪問服務器的時候連接成功,但是使用ListFile()獲取不到任何文件?(就是第三個問題描述的)
-
想要移動FTP服務器里的文件,如何辦?(我使用了Rename操作來完成的。把原有的名字)
-
具體業務實現。(你自己厘清自己的實現思路,無論是讀取指定文件夾的內容,還是上傳或者下載,亦或者是對文件名處理,split拼接,判斷指定類型等等。都不是什么難的操作。按照自己的需求,自己去設計實現吧。)
-
上傳下載讀取的話,都是使用流的操作。(看代碼吧。)
-
聊一下關於修改FTP工作空間的操作和設置數據傳輸模式。(這個先簡單的提供兩行代碼,可能就已經能夠解決你的疑問了)
//修改工作目錄: 就是說,你要處理哪里的文件什么的。看一下Doc就知道了。
ftpClient.changeWorkingDirectory(pathname);
//開啟本地傳輸模式。(還有其他幾種模式。Doc文檔中有。自行查閱)
ftpClient.enterLocalPassiveMode();
我這里提煉出來了幾個方法,新手使用的話,或者有問題的看代碼自行參悟吧。比較簡單,這里也主要就是對代碼上的記錄。(為了保護隱私,隱藏了一些隱私數據和業務處理類。)
關於代碼,先說注意事項:
- 用完連接,記得關。
- 用完流,記得關。
- 有異常,記得處理。
下面是具體的代碼:
- 建立FTP連接。
public FTPClient ftpClient = null;
//ftp服務器IP
public String hostname = "XXX10.1001.11";
//ftp服務器端口號默認為21
public Integer port = XXX;
//ftp登錄賬號
public String username = "XXX";
//ftp登錄密碼
public String password = "XXX";
public void initFtpClient() {
ftpClient = new FTPClient();
ftpClient.setControlEncoding("utf-8");
try {
System.out.println("connecting...ftp服務器:"+hostname+":"+port);
ftpClient.connect(hostname, port); //連接ftp服務器
ftpClient.login(username, password); //登錄ftp服務器
int replyCode = ftpClient.getReplyCode(); //是否成功登錄服務器
if(!FTPReply.isPositiveCompletion(replyCode)){
System.out.println("connect failed...ftp服務器:"+hostname+":"+port);
}
System.out.println("connect successfu...ftp服務器:"+hostname+":"+port);
}catch (MalformedURLException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
調用完 intFTPClient()方法之后,就可以使用ftpClient 來操作FTP服務器了。
- 上傳.
/**
* 上傳文件
* @param pathname ftp服務保存地址
* @param fileName 上傳到ftp的文件名
* @param originfilename 待上傳文件的名稱(絕對地址) *
* @return*
**/
public boolean uploadFile( String pathname, String fileName,String originfilename){
boolean flag = false;
InputStream inputStream = null;
try{
System.out.println("開始上傳文件");
inputStream = new FileInputStream(new File(originfilename));
initFtpClient();
ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
CreateDirecroty(pathname);
ftpClient.makeDirectory(pathname);
ftpClient.changeWorkingDirectory(pathname);
ftpClient.enterLocalPassiveMode();
ftpClient.storeFile(fileName, inputStream);
inputStream.close();
ftpClient.logout();
flag = true;
System.out.println("上傳文件成功");
}catch (Exception e) {
System.out.println("上傳文件失敗");
e.printStackTrace();
return false;
}finally{
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
flag = false;
}
}
if(null != inputStream){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
flag = false;
}
}
}
return flag;
}
- 下載
//我這里在讀到文件流的時候,沒有保存到本地,直接在程序里面讀取轉換里面的內容,繼續使用了。
//如果有需要的話,我簡單的說下思路。就是 用 ftpClient調用指定文件下的文件,調用 FTPFile[] ftpFileArr = ftpClient.listFiles(path);
//后續 InputStream in = ftpClient.retrieveFileStream(fileName)。 獲取到具體的文件流。然后后續操作 保存流到本地即可。
- 移動文件(通過Rename完成)
/**
*
* @param nameSet 需要移動的文件目錄清單
* @param fromPath 從哪個目錄移動
* @param toPath 要移動的目錄(從根目錄開始寫。如:/code/yes/:根目錄下的code目錄下的yes目錄
* @return 返回成功或者失敗
* 注意:目錄的話,以/結尾
*/
public boolean moveFile(List<String> nameSet,String fromPath,String toPath){
//name格式:/code/yesdawaTest1.txt 、/code/yesdawaTest2.txt
if (nameSet != null && nameSet.size() > 0) {
for (String s : nameSet) {
try {
//獲取連接:因為一次連接改多個文件只能有一個生效。這里每次修改文件的時候,獲取一次新的鏈接
initFtpClient();
//改變工作目錄
ftpClient.changeWorkingDirectory(fromPath);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
String[] split = s.split("/");
String name = "";
if (split.length > 0) {
name = split[split.length - 1];
}
boolean rename = ftpClient.rename(name, toPath + name);
if (rename) {
System.out.println(name + "成功移動到:" + toPath + name);
}
ftpClient.logout();
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}
return true;
}
- 對文件名或文件類型的處理和判斷。(僅供參考)
//檢查指定/path目錄下,是否有.txt結尾的文件。如果有,返回符合要求的.
/**
*
* @param path:要查找的文件目錄,如 /code:根目錄下的code目錄
* @param ext:要查找的文件類型擴展名,如 .txt
* @return 返回:符合查找要求的 文件名清單。
*
* 返回的 文件名清單:可以先用於處理數據,然后再處理數據成功后,移動這些文件到其他目錄下。
*/
public List<String> checkExistFile(String path, String ext){
//定義一個返回集合:
List<String> tNameSet = new ArrayList<>();
//連接服務器
initFtpClient();
try {
//改變工作目錄
ftpClient.changeWorkingDirectory(path);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
String[] strings = ftpClient.listNames(path);
if (strings.length > 0) {
for (String string : strings) {
//如果文件名的長度(帶后綴名的)>4 . 才可能是 .txt 結尾的。
if (string.length() > ext.length()) {
//取得文件后綴名
String substring = string.substring(string.length() - ext.length());
if (ext.equals(substring)) {
System.out.println("目前正在處理文件:" + string);
tNameSet.add(string);
}
}
}
}
ftpClient.logout();
} catch (IOException e) {
System.out.println("讀取:"+path+" 目錄失敗");
e.printStackTrace();
}
//返回:符合要求的文件 名字 清單
return tNameSet;
}
- 關閉ftp連接
/**
* 關閉FTP服務鏈接
* @throws IOException
*/
public static void disConnection(FTPClient ftpClient){
try {
if(ftpClient.isConnected()){
ftpClient.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
OK,以上就是所有問題,有問題可以發郵件聯系:16637462812@163.com。 歡迎溝通交流。
