前一段时间,自己写了一个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;
}
}