至于断点续传的设计很简单,服务端留有一个定位参数,每次读取文件之前,都先定位,然后客户端在调用WebService接口之前,先取得本地该文件的大小,再把该值作为定位参数传过去就OK,最后根据接收到的字符串的长度为0时作为文件传输完毕的判断依据。
另外如果想做到实时取得文件传输的进度的话,可以设计一个地址参数,根据累计传输大小来返回即可,在这里略过。
文件上传部分代码反过来即可,这里也略过。
xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="">
<service>
<name>HelloWorldService</name>
<namespace>http://localhost:8090/WebServiceTest
</namespace>
<serviceClass>service.IHelloWorld</serviceClass>
<implementationClass>service.HelloWorldImpl
</implementationClass>
</service>
</beans>
接口文件:
package service;
public interface IHelloWorld {
//sayHello 方法声明了Web服务对外暴露的接口
public String download(String filename,long startpost) throws Exception ; }服务端文件:
package service;
import java.io.File;
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile;import javax.activation.DataHandler;
import javax.servlet.http.HttpServletRequest;import org.codehaus.xfire.transport.http.XFireServletController;
import org.codehaus.xfire.util.Base64;public class HelloWorldImpl implements IHelloWorld {
private RandomAccessFile raf=null; /** * @filename:要下载的文件名(全名); * @startpost:由于WebService不能一次性传输大文件,所以使用startpost定位参数来实现断点续传; * :把文件内容Byte[]转换成Base64编码返回; */ public String download(String filename,long startpost) throws Exception { //System.out.println("要下载的文件名是:"+filename); int BUFFER_LENGTH = 1024 * 20;//一次性读入大小 int SLEEP_TIME=250;//循环读次数 int time=0; long filesize=0; String ret=null; String str=null; File file=new File("e:\\",filename); if (file.exists()) { filesize=file.length(); FileInputStream fis = null; try { fis = new FileInputStream(file);StringBuffer sb = new StringBuffer();
//System.out.println("定位:"+startpost); fis.skip(startpost);//先定位 byte[] buffer = new byte[BUFFER_LENGTH]; int count; while (time<SLEEP_TIME && (count = fis.read(buffer)) != -1 ) { sb.append(Base64.encode(buffer,0,count)); time++; } ret = sb.toString(); //System.out.println("输出:"+ret.length()); } catch (FileNotFoundException e) { e.printStackTrace(); throw new Exception("出错啦!", e); } catch (IOException e) { e.printStackTrace(); throw new Exception("出错啦!", e); } catch (Exception e) { throw new Exception("出错啦!", e); } finally { fis.close(); } }return ret;
}}
客户端文件:
package service;
import java.io.File;
import java.io.RandomAccessFile; import java.net.MalformedURLException; import java.net.URL;import org.codehaus.xfire.client.Client;
import org.codehaus.xfire.transport.http.HttpTransport; import org.codehaus.xfire.util.Base64; public class DynamicClientTest { public Object[] getWebService(String surl,String saction,Object[] objarr) throws MalformedURLException,Exception { Client client = new Client(new URL(surl)); //client.setProperty("mtom-enabled", "true"); client.setProperty(HttpTransport.CHUNKING_ENABLED,"true"); Object[] results = client.invoke(saction, objarr); return results;}
public static void main(String[] args) throws MalformedURLException,Exception { String surl="";Long start=System.currentTimeMillis();
File file=new File("e:\\","test.rar"); RandomAccessFile raf=new RandomAccessFile(file,"rw"); //System.out.println("文件大小:"+file.length()); raf.seek(file.length());//先定位 boolean isend=false; while (!isend){ Object[] results3=web.getWebService(surl, "download", new Object[]{"GMS.rar",file.length()}); String data=(String)results3[0]; //System.out.println("返回大小:"+data.length()); byte[] bytes = Base64.decode(data); raf.write(bytes); raf.skipBytes(data.length());//顺序写 if(data.length()<=0){isend=true;} } raf.close();Long end=System.currentTimeMillis();
System.out.println("用时:"+(end-start)); } }