|
常用链接
留言簿(8)
随笔分类
随笔档案
相册
搜索
最新评论
阅读排行榜
评论排行榜
Powered by: 博客园
模板提供:沪江博客
|
|
|
|
|
发新文章 |
|
|
很多人都碰到ftp的上传下载文件的实现,很容易碰到一些问题,最难解决的是乱码的问题,
在网上搜索了挺多,也没人能讲得清楚详细的,这里把自己实现的程序贴出来,供大家参考。
以后碰到这些问题,可以自己多看看java的API,还是很有帮助的。
另外在实现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)支持中文,实现了此类继承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上传下载的处理类,主要是注意对连接的处理和一些细节问题,也比较简单,就是要仔细点,这里不啰嗦了。
/** *//**
*
* <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;
/** *//**
* 构造函数,用配置文件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();
}
}
/** *//**
* 构造函数 用传入的参数进行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 "连接错误或服务器上无此路径!";
}
}
/** *//**
* 根据传入的文件路径进行连接。
*
* @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 下载文件的大小,以字节为单位,下载失败返回-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 指定文件的大小,以字节为单位,读取文件异常返回-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;
}
/** *//**
* 在当前目录下创建文件夹
*
* @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;
}
}
|
|