前一段时间,自己写了一个java项目发布在一个免费的java平台上但是该平台给项目的是虚拟路径并不能上传文件。后来想到应用ftp作为上传文件的存储器。
ftp上传的工具类有sun(sun.net.*)和apache(org.apache.commons.net.ftp.* 这个需要在项目中加载commons-net-1.4.1.jar包)。这次我提供的是基于FtpClient(sun)实现的上传文件,因为用FTPClient(apache)想要强行加入上传文件的速度检测比较麻烦,暂时没有处理以后在整理。
下面说一下我的实现思路:UploadFtp1.java 负责上传和下载的方法实现,ExStreams.java 重写其中的方法copy()把文件读取的循环中添加上上传的监听 ,UploadProgressListener.java 进度的实体类
UploadFtp1.java
package upload; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import sun.net.TelnetInputStream; import sun.net.TelnetOutputStream; public class UploadFtp1 { private sun.net.ftp.FtpClient client=null; private String strServerAddr=""; private int iServerPort=0; private String strUserName=""; private String strUserPwd=""; // 监测连接是否正常 public boolean CheckConn(){ boolean bRet=false; try{ client.pwd(); bRet=true; }catch(IOException ex){ bRet=false; } return bRet; } //设置数据的传输格式为二进制,如果是文本以外的数据如图片应该用此方法 private boolean Binary(){ boolean bRet=false; try{ client.binary(); bRet=true; }catch(IOException ex){ bRet=false; } return bRet; } //单字节字符编码方案,用于基于文本的数据 private boolean Ascii(){ boolean bRet=false; try{ client.ascii(); bRet=true; }catch(IOException ex){ bRet=false; }return bRet; } public boolean DisConnect(){ boolean bRet=false; try{ client.closeServer(); bRet=true; }catch(IOException ex){ bRet=false; } return bRet; } /** * 用书上传本地文件到ftp服务器上 * @param strSrcFile 上传文件的本地路径 * @param strDestFile 上传到ftp的文件路径 * @return */ public boolean PutFile(String strSrcFile,String strDestFile){ boolean bRet=false; try{ Binary(); TelnetOutputStream fput=client.put(strDestFile); BufferedOutputStream out = new BufferedOutputStream(fput); File fi = new File(strSrcFile); InputStream srcFile = new FileInputStream(fi); BufferedInputStream in = new BufferedInputStream(srcFile); UploadProgressListener listener = new UploadProgressListener(); ExStreams.copy(in, out,in.available(),true,listener); //一定要关闭文件流 in.close(); out.close(); System.out.print("put file suc from "+strSrcFile+" to "+strDestFile+"\r\n"); } catch (IOException ex){ bRet=false; ex.printStackTrace(); } return bRet; } /** * 从ftp上下载所需要的文件 * @param strSrcFile 在ftp上路径及文件名 * @param strDestFile 要保存的本地的路径 * @return */ public boolean GetFile(String strSrcFile,String strDestFile){ boolean bRet=false; try{ Binary(); TelnetInputStream fget=client.get(strSrcFile); //为了读取ftp该文件的大小,为了计算下载速度和百分比 int fileSize = -1; client.sendServer("SIZE "+strSrcFile+"\r\n"); int res = client.readServerResponse();//z注意:这里的组合使用是必须得 sendServer 后到 readServerResponse if(res==213){ String msg= client.getResponseString(); try{ fileSize = Integer.parseInt(msg.substring(3).trim()); } catch(Exception ex){;} } BufferedInputStream in = new BufferedInputStream(fget); File fi = new File(strDestFile); OutputStream srcFile = new FileOutputStream(fi); BufferedOutputStream out = new BufferedOutputStream(srcFile); UploadProgressListener listener = new UploadProgressListener(); listener.setFileName(strDestFile); ExStreams.copy(in, out,fileSize, true,listener); //一定要关闭文件流 in.close(); out.close(); System.out.print("get file suc from "+strSrcFile+" to "+strDestFile+"\r\n"); } catch (IOException ex){ bRet=false; ex.printStackTrace(); } return bRet; } /** * 连接ftp服务器 * @param ServerAddr * @param ServerPort * @param UserName * @param UserPwd * @return */ public boolean Connect(String ServerAddr,int ServerPort,String UserName,String UserPwd){ boolean bRet=false; client=new sun.net.ftp.FtpClient(); this.strServerAddr=ServerAddr; this.iServerPort=ServerPort; this.strUserName=UserName; this.strUserPwd=UserPwd; try{ client.openServer(strServerAddr,iServerPort); client.login(strUserName, strUserPwd); System.out.print("connect succeed\n"); bRet=true; } catch (IOException ex) { ex.printStackTrace(); bRet=false; } return bRet; } /** * ftp连接一致连 直到连接成功。 * @return */ public boolean ConnectTillSuc(){ return this.ConnectTillSuc(this.strServerAddr, this.iServerPort, this.strUserName, this.strUserPwd); } // 连接,直到成功 public boolean ConnectTillSuc(String ServerAddr,int ServerPort,String UserName,String UserPwd){ while(!this.Connect(ServerAddr, ServerPort, UserName, UserPwd)){ try { System.out.print("connect failed,retry...\n"); Thread.sleep(3000); }catch (InterruptedException e) { e.printStackTrace(); } } return true; } public static void main(String[] args) throws IOException, InterruptedException { UploadFtp1 client=new UploadFtp1(); boolean b=client.ConnectTillSuc("",21,"",""); //client.PutFile("D:\\code.jar", "/test/1344439.jar"); client.GetFile("/test/1344469.jar", "D:\\4044-1.jar"); client.DisConnect(); } }
ExStreams.java
package upload; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class ExStreams { public static long copy(InputStream pInputStream, OutputStream pOutputStream,long size,boolean pClose,UploadProgressListener uploadListener) throws IOException { return copy(pInputStream, pOutputStream,size, pClose,new byte[8192],uploadListener); } public static long copy(InputStream pIn, OutputStream pOut,long size,boolean pClose,byte[] pBuffer,UploadProgressListener uploadListener) throws IOException { OutputStream out = pOut; InputStream in = pIn; try { long total = 0L; int res; while (true) { res = in.read(pBuffer); if (res == -1) { break; } if (res > 0) { total += res; if (out != null) { out.write(pBuffer, 0, res); System.out.println("文件的大小"+size+"读取的大小"+total); uploadListener.update(total, size, 0); } } } if (out != null) { if (pClose) out.close(); else { out.flush(); } out = null; } in.close(); in = null; return total; } finally { if (in != null) try { in.close(); } catch (Throwable t) { } if ((pClose) && (out != null)) try { out.close(); } catch (Throwable t) { } } } }
UploadProgressListener.java
package upload; import java.io.Serializable; public class UploadProgressListener implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private volatile long bytesRead = 0L; private volatile long contentLength = 0L; private String fileName = ""; private long megaBytes = -1L; public void update(long aBytesRead, long aContentLength, int anItem) { this.bytesRead = (aBytesRead / 1024L); this.contentLength = (aContentLength / 1024L); if (this.contentLength == 0L) { this.contentLength = 1L; } long mBytes = aBytesRead / 1048576L; if (this.megaBytes == mBytes) { return; } this.megaBytes = mBytes; System.out.println("上传或者下载文件:" + this.fileName + ",文件的大小:" + aBytesRead + "/" + aContentLength); } public long getBytesRead() { return this.bytesRead; } public long getContentLength() { return this.contentLength; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } }