|  | 
		
			| 常用链接留言簿(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; 
  } 
  }     |  |