|
常用鏈接
留言簿(8)
隨筆分類
隨筆檔案
相冊
搜索
最新評論

閱讀排行榜
評論排行榜
Powered by: 博客園
模板提供:滬江博客
|
|
|
|
|
發(fā)新文章 |
|
|
很多人都碰到ftp的上傳下載文件的實現(xiàn),很容易碰到一些問題,最難解決的是亂碼的問題,
在網上搜索了挺多,也沒人能講得清楚詳細的,這里把自己實現(xiàn)的程序貼出來,供大家參考。
以后碰到這些問題,可以自己多看看java的API,還是很有幫助的。
另外在實現(xiàn)ftp上傳下載的時候,還要多考慮一下上傳下載失敗或者網絡連接斷開的問題,
這需要不同情況不同的處理了,這里不作描述了。
1> 解決亂碼的關鍵
FtpClient的默認編碼格式ISO-8859-1,很多地方都提到了sun.net.NetworkClient類中的encoding屬性,
能設置ftp的編碼格式,但這個屬性是不能直接訪問的,可以通過繼承FtpClient類的方式來訪問;
 /** *//**
*
* <p>Title: FtpOperation.java</p>
* <p>Description: 為了改變FtpClient的默認編碼格式ISO-8859-1為utf-8(或GBK)支持中文,實現(xiàn)了此類繼承FtpClient</p>
* <p>Copyright: Copyright (c) 2009</p>
* <p>Company: </p>
* @author
* @version 1.0
*
*/
 public class CustomFtpClient extends FtpClient {

 private CustomFtpClient() {
super();
}
 /** *//**
* 初始化時必須指定服務器的編碼格式
* @param encodingStr
*/
 protected CustomFtpClient(String encodingStr) {
super();
sun.net.NetworkClient.encoding = encodingStr;
}

 /** *//**
* 設置連接編碼
* @param encodingStr
* void
*
*/
 protected void setEncoding(String encodingStr) {
sun.net.NetworkClient.encoding = encodingStr;
}
 /** *//**
* 取得編碼格式
* @return
* String
*
*/
 protected String getEncoding() {
return sun.net.NetworkClient.encoding ;
}
}

2. 這個類就是ftp上傳下載的處理類,主要是注意對連接的處理和一些細節(jié)問題,也比較簡單,就是要仔細點,這里不啰嗦了。
 /** *//**
*
* <p>
* Title: FtpUtils.java
* </p>
* <p>
* Description: FTP相關的操作類,提供ftp登錄、ftp上傳文件、ftp下載文件等功能<br/>
* 使用說明:<br/>
* FtpUtil ftp = new FtpUtil("localhost", "test", "test", "GBK","test", 21); //初始化信息<br/>
* ftp.connectServer();<br/>
* 如果需要以ascii格式操作,要調用方法ftp.ftpClient.ascii();<br/>
* **ftp的相關操作**<br/>
* ftp.closeConnect();<br/>
* </p>
* <p>
* Copyright: Copyright (c) 2009
* </p>
* <p>
* Company:
* </p>
*
* @author
* @version 1.0
*
*/
 public class FtpUtil {

private String serverIp = ""; // 服務器ip

private String userName = ""; // 登錄服務器用戶名

private String password = ""; // 登錄服務器密碼

private String path = ""; // 服務器路徑

private int serverPort = -1; // 服務器端口號
private String encoding = "GBK"; //服務器端編碼格式

protected CustomFtpClient ftpClient = null;

OutputStream os = null;

FileInputStream is = null;

 /** *//**
* 構造函數(shù),用配置文件asiainfo.properties中配置的ftp信息進行操作,
* 需要設置服務器的編碼格式PLANDEMO_FTP_ENCODING="GBK"(ftp服務器編碼格式)。
* @param encodingStr
* @throws Exception
*/
 public FtpUtil() throws Exception {
 try {
this.serverIp = Configure.getInstance().getProperty(
"PLANDEMO_FTP_SERVER"); // 默認服務器
this.userName = Configure.getInstance().getProperty(
"PLANDEMO_FTP_USERNAME"); // 默認用戶
this.password = Configure.getInstance().getProperty(
"PLANDEMO_FTP_PASSWORD"); // 默認密碼
this.path = Configure.getInstance().getProperty("PLANDEMO_FTP_DIR"); // 默認路徑
this.encoding = StringUtil.obj2Str(Configure.getInstance().getProperty("PLANDEMO_FTP_ENCODING"),"GBK"); // 默認路徑
 } catch (Exception ex) {
ex.getMessage();
}
}

 /** *//**
* 構造函數(shù) 用傳入的參數(shù)進行ftp操作,必須確定ftp服務器的編碼格式
* @param ip
* 服務器ip地址
* @param name
* 登錄服務器用戶名
* @param pwd
* 登錄服務器密碼
* @param encodingStr ftp服務器的編碼格式
* @param defPath
* 服務器設置的路徑,為空則為默認設置的路徑
* @param port
* 如果采用服務器默認值設置為-1,其他需要設置
*/
 public FtpUtil(String ip, String name, String pwd, String encodingStr, String defPath, int port) {
this.serverIp = ip;
this.userName = name;
this.password = pwd;
this.encoding = StringUtil.obj2Str(encodingStr,"GBK");
this.path = defPath;
this.serverPort = port;
}

 /** *//**
*
* 連接服務器
*
* @return String 如果連接成功返回"true",失敗則返回"連接錯誤或服務器上無此路徑!"
*
*/
 public String connectServer() {
 try {
ftpClient = new CustomFtpClient(this.encoding);
 if (this.serverPort > 0) {
ftpClient.openServer(this.serverIp, this.serverPort);
 } else {
ftpClient.openServer(this.serverIp);
}

ftpClient.login(this.userName, this.password);
 if (this.path != null && this.path.trim().length() > 0) {
ftpClient.cd(this.path);
}
ftpClient.binary();
return "true";
 } catch (Exception ex) {
ex.printStackTrace();
return "連接錯誤或服務器上無此路徑!";
}
}

 /** *//**
* 根據(jù)傳入的文件路徑進行連接。
*
* @param hostPath
* 傳入的服務器路徑
* @return String 如果連接成功返回"true",沒有該路徑返回"連接錯誤或服務器上無此路徑!"
*
*/
 public String connectServer(String hostPath) {
 try {
ftpClient = new CustomFtpClient(this.encoding);
 if (this.serverPort > 0) {
ftpClient.openServer(this.serverIp, this.serverPort);
 } else {
ftpClient.openServer(this.serverIp);
}
ftpClient.login(this.userName, this.password);
 if (hostPath != null && hostPath.trim().length() > 0) {
ftpClient.cd(hostPath);
}
ftpClient.binary();
return "true";
 } catch (Exception ex) {
ex.printStackTrace();
return "連接錯誤或服務器上無此路徑!";
}
}

 /** *//**
*
* 關閉連接 void
*
*/
 public void closeConnect() {
 try {
 if (is != null) {
is.close();
}
 if (os != null) {
os.close();
}
 if (ftpClient != null && ftpClient.serverIsOpen()) {
ftpClient.closeServer();
}
 } catch (Exception ex) {
ex.printStackTrace();
}
}

 /** *//**
*
* 從ftp下載文件到本地
*
* @param filename 服務器上的文件名(與服務器路徑的相對路徑和文件名)
* @param newfilename 本地生成的文件名(不帶路徑會下載到默認的項目的根目錄)
* @return
* long 下載文件的大小,以字節(jié)為單位,下載失敗返回-1
*
*/
 public long downloadFile(String filename, String newfilename) {
TelnetInputStream is = null;
FileOutputStream os = null;
long result =0;
 try {
is = ftpClient.get(filename);
java.io.File outfile = new java.io.File(newfilename);
os = new FileOutputStream(outfile);
byte[] bytes = new byte[1024];
int c;
 while ((c = is.read(bytes)) != -1) {
os.write(bytes, 0, c);
result += c;
}
return result;
 } catch (IOException e) {
e.printStackTrace();
return -1;
 } finally {
 try {
 if (is != null) {
is.close();
}
 if (os != null) {
os.close();
}
 } catch (IOException e) {
e.printStackTrace();
}
}
}
 /** *//**
*
* 獲取ftp服務器上的文件大小
* @param filename
* @return
* long 指定文件的大小,以字節(jié)為單位,讀取文件異常返回-1
*
*/
 public long getFileSize(String filename) {
TelnetInputStream is = null;
long result =0;
 try {
is = ftpClient.get(filename);
byte[] bytes = new byte[1024];
int c;
 while ((c = is.read(bytes)) != -1) {
result += c;
}
return result;
 } catch (IOException e) {
e.printStackTrace();
return -1;
 } finally {
 try {
 if (is != null) {
is.close();
}
 if (os != null) {
os.close();
}
 } catch (IOException e) {
e.printStackTrace();
}
}
}

 /** *//**
*
* ftp上傳 如果服務器段已存在名為filename的文件夾,該文件夾中與要上傳的文件夾中同名的文件將被替換
*
* @param filename
* 要上傳的文件(或文件夾)名
* @return
* boolean
*
*/
 public boolean upload(String filename) {
String newname = "";
 if (filename.indexOf("/") > -1) {
newname = filename.substring(filename.lastIndexOf("/") + 1);
 } else if(filename.indexOf("\\") > -1) {
newname = filename.substring(filename.lastIndexOf("\\") + 1);
 }else {
newname = filename;
}
return upload(filename, newname);
}

 /** *//**
*
* ftp上傳 如果服務器段已存在名為newName的文件夾,該文件夾中與要上傳的文件夾中同名的文件將被替換
*
* @param fileName
* 要上傳的文件(或文件夾)名
* @param newName
* 服務器段要生成的文件(或文件夾)名
* @return
* boolean
*
*/
 public boolean upload(String fileName, String newName) {
 try {
File file_in = new File(fileName);// 打開本地待上傳的文件
 if (!file_in.exists()) {
throw new Exception("此文件或文件夾[" + file_in.getName() + "]有誤或不存在!");
}
 if (file_in.isDirectory()) {
upload(file_in.getPath(), newName, ftpClient.pwd());
 } else {
uploadFile(file_in.getPath(), newName);
}

 if (is != null) {
is.close();
}
 if (os != null) {
os.close();
}
return true;
 } catch (Exception e) {
e.printStackTrace();
System.err.println("Exception e in Ftp upload(): " + e.toString());
return false;
 } finally {
 try {
 if (is != null) {
is.close();
}
 if (os != null) {
os.close();
}
 } catch (IOException e) {
e.printStackTrace();
}
}
}

 /** *//**
* 上傳文件或者文件夾
*
* @param fileName
* @param newName
* @param path
* @throws Exception
*/
private void upload(String fileName, String newName, String path)
 throws Exception {
File file_in = new File(fileName);// 打開本地待長傳的文件
 if (!file_in.exists()) {
throw new Exception("此文件或文件夾[" + file_in.getName() + "]有誤或不存在!");
}
 if (file_in.isDirectory()) {
 if (!isDirExist(newName)) {
createDir(newName);
}
ftpClient.cd(newName);
File sourceFile[] = file_in.listFiles();
 for (int i = 0; i < sourceFile.length; i++) {
 if (!sourceFile[i].exists()) {
continue;
}
 if (sourceFile[i].isDirectory()) {
this.upload(sourceFile[i].getPath(), sourceFile[i]
.getName(), path + File.separator + newName);
 } else {
this.uploadFile(sourceFile[i].getPath(), sourceFile[i]
.getName());
}
}
 } else {
uploadFile(file_in.getPath(), newName);
}
ftpClient.cd(path);
}

 /** *//**
*
* upload 上傳文件
* @param filename
* 要上傳的文件名
* @param newname
* 上傳后的新文件名
* @return
* @throws Exception
* long 已經上傳文件的大小,異常返回-1
*
*/
 public long uploadFile(String filename, String newname) throws Exception {
TelnetOutputStream os = null;
FileInputStream is = null;
long result =0;
 try {
java.io.File file_in = new java.io.File(filename);
 if (!file_in.exists()) {
return -1;
}
os = ftpClient.put(newname);
is = new FileInputStream(file_in);
byte[] bytes = new byte[1024];
int c;
 while ((c = is.read(bytes)) != -1) {
os.write(bytes, 0, c);
result += c;
}
return result;
 } finally {
 if (is != null) {
is.close();
}
 if (os != null) {
os.close();
}
}
}

 /** *//**
* 檢查文件夾在當前目錄下是否存在
*
* @param dir
* @return
*/
 public boolean isDirExist(String dir) {
String pwd = "";
 try {
pwd = ftpClient.pwd();
ftpClient.cd(dir);
ftpClient.cd(pwd);
 } catch (Exception e) {
return false;
}
return true;
}

 /** *//**
* 在當前目錄下創(chuàng)建文件夾
*
* @param dir
* @return
* @throws Exception
*/
 public boolean createDir(String dir) {
 try {
ftpClient.ascii();
StringTokenizer s = new StringTokenizer(dir, File.separator); // sign
s.countTokens();
String pathName = ftpClient.pwd();
 while (s.hasMoreElements()) {
pathName = pathName + File.separator + (String) s.nextElement();
 try {
ftpClient.sendServer("MKD " + pathName + "\r\n");
 } catch (Exception e) {
e.printStackTrace();
return false;
}
ftpClient.readServerResponse();
}
ftpClient.binary();
return true;
 } catch (IOException e1) {
e1.printStackTrace();
return false;
}
}

 /** *//**
*
* 取得相對于當前連接目錄的某個目錄下所有文件列表
*
* @param subPath
* 連接目錄下的某個子目錄開始的路徑,如果是連接目錄則為空
* @return List 返回的結果集合,對象類型為文件名稱的字符串
*
*/
 public List<String> getFileList(String subPath) {
 if(subPath==null || subPath.trim().length()<1) {
return getFileList();
}
List<String> list = new ArrayList<String>();
BufferedReader dis;
 try {
dis = new BufferedReader(new InputStreamReader(ftpClient.nameList(subPath),ftpClient.getEncoding()));
String filename = "";
 while ((filename = dis.readLine()) != null) {
list.add(filename);
}
 } catch (IOException e) {
e.printStackTrace();
}
return list;
}
 /** *//**
*
* 取得相對于當前連接目錄的某個目錄下所有文件列表
*
* @param subPath
* 連接目錄下的某個子目錄開始的路徑,如果是連接目錄則為空
* @return List 返回的結果集合,對象類型為文件名稱的字符串
*
*/
 public List<String> getFileList() {
List<String> list = new ArrayList<String>();
BufferedReader dis;
 try {
dis = new BufferedReader(new InputStreamReader(ftpClient.list()));
String filename = "";
 while ((filename = dis.readLine()) != null) {
list.add(filename);
}
 } catch (IOException e) {
e.printStackTrace();
}
return list;
}
}
|
|