骑猪闯天下

J2ME随笔,记录成长的脚步

统计

留言簿(3)

阅读排行榜

评论排行榜

[J2ME]断点续传


断点续传的头信息设置:
conn.setRequestProperty("RANGE", "bytes=" + size + "-"); //断点续传

项目中使用断点续传,头信息的属性按上面设置好了,但无论怎么测试,就是不能实现,费了一天又一个晚上的功夫才查到问题所在,在使用断点续传的时候,头信息的联网方式设为了post,导致无法续传!

实践证明要实现断点续传:联网方式必须使用get方式,或默认不设置。

以下是断点续传的部分代码:
package com.xuudoo.booking;

import java.io.DataInputStream;
import java.io.IOException;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.rms.InvalidRecordIDException;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreNotOpenException;

import com.xuudoo.ewl.EWLScreen;

public class DownloadTool implements Runnable {
    
public XItem item;//当前下载的item
    public String imageName;//当前下载的书名
    public int FocusID;//当前下载的ID

    
public HttpConnection conn = null;
    
public DataInputStream dis = null;
    
public RMSRecorderIfno rms;//存放下载的漫画数据
    public RMSRecorderIfno rms1;//存放下载的url和数据节点个数
    public RMSRecorderIfno rms2; //存放废字节长度

    
public DownloadTool(XItem xitem,int focusID) {
        item 
= xitem;
        imageName 
= xitem.itemId;
        FocusID 
= focusID;
    }


    
public void run() {
        UIManager.isLoading 
= true;
        
try {
            System.gc();
            String url 
= "";
            
if (item.isResume){
                downloadFileagain(url);
            }
else{
                url 
= UIManager._currMgz.mgzLocate;
                downloadFile(url);
            }

            UIManager._instance.doLoop();
            
do {
                
if (UIManager._instance.downloadurl == null)
                    
break;
                
for (int i = 0; i < UIManager._instance.downloadurl.size();) {
                    url 
= (String) UIManager._instance.downloadurl.elementAt(i);
                    item 
= (XItem) UIManager._instance.downloaditem.elementAt(i);
                    imageName 
= item.itemId;
                    FocusID 
= Integer.parseInt((String) UIManager._instance.downloadid.elementAt(i));
                    
if (item.isResume)
                        downloadFileagain(url);
                    
else
                        downloadFile(url);
                    
break;
                }

                UIManager._instance.downloadurl.removeElement(url);
                UIManager._instance.downloaditem.removeElement(item);
                UIManager._instance.downloadid.removeElement(Integer.toString(FocusID));
                UIManager._instance.doLoop();
            }
 while (UIManager._instance.downloadurl != null && UIManager._instance.downloadurl.size() >= 1);
        }
 catch (Exception e) {
            
if(BookingMidlet.DEBUG)
                e.printStackTrace();
        }
 finally {
            UIManager.isLoading 
= false;
            UIManager._instance.doLoop();
        }

    }


    
public synchronized void StopDownLoadThread() {
        
if (conn != null{
            notify();
            Close();
        }

    }


    
public synchronized void CloseMidlet() {
        
if (dis != null{
            
try {
                dis.close();
            }
 catch (IOException e) {
                e.printStackTrace();
            }

            dis 
= null;
        }

        
if (conn != null{
            notify();
            
try {
                conn.close();
            }
 catch (IOException e) {
                e.printStackTrace();
            }

            conn 
= null;
        }

        
if (rms != null{
            rms.close();
            rms  
= null;
        }

        
if (rms1 != null{
            rms1.close();
            rms1  
= null;
        }

        
if (rms2 != null{
            rms2.close();
            rms2  
= null;
        }

        
if(UIManager._instance._percent != null)
            UIManager._instance._percent 
= null;
    }

    
    
private void Close() {
        
if (dis != null{
            
try {
                dis.close();
            }
 catch (IOException e) {
                e.printStackTrace();
            }

            dis 
= null;
        }

        
if (conn != null{
            
try {
                conn.close();
            }
 catch (IOException e) {
                e.printStackTrace();
            }

            conn 
= null;
        }

        
try {
            Thread.sleep(
500);
            
if(BookingMidlet.DEBUG)
                System.out.println(
"-----关闭连接和RMS.");
        }
 catch (Exception ex) {
            
//
        }

        
if (rms != null{
            rms.close();
            rms  
= null;
        }

        
if (rms1 != null{
            rms1.close();
            rms1  
= null;
        }

        
if (rms2 != null{
            rms2.close();
            rms2  
= null;
        }

        
if(UIManager._instance._percent != null)
            UIManager._instance._percent 
= null;
    }


    
private int xcblength = 0//整个xcb记录个数

    
public void downloadFile(String url){
        
if (RMSRecorderIfno.exists("002_" + imageName + "_mgz"))
            RMSRecorderIfno.delete(
"002_" + imageName + "_mgz");
        rms 
= new RMSRecorderIfno();
        rms.open(
"002_" + imageName + "_mgz"true);
        
//
        rms2 = new RMSRecorderIfno();
        
if (RMSRecorderIfno.exists("002_" + imageName + "_byte")) {
            RMSRecorderIfno.delete(
"002_" + imageName + "_byte");
        }

        rms2.open(
"002_" + imageName + "_byte"true);

        rms1 
= new RMSRecorderIfno();
        rms1.open(
"002_" + imageName + "_url"true);
        
byte[] urlbyte = url.getBytes();
        rms1.openWriteStream();
        rms1.write(urlbyte);
        rms1.addRecord(rms1.saveStreamToByteArray());
        rms1.closeWriteStream();
        String precentstr 
= "0";// 下载进度的百分比
        
        
try {
            
//S40_V3版本需通过cmwap才能下载
            if (!BookingMidlet.useProxy){
                conn 
= (HttpConnection)Connector.open(url);
            }
 else {
                String remainUrl 
= url.substring("http://".length());
                
int index = remainUrl.indexOf("/");
                String path 
= "";
                
if (index != -1{
                    path 
= remainUrl.substring(index);
                    remainUrl 
= remainUrl.substring(0, index);
                }

                String host 
= "";
                String port 
= "";
                index 
= remainUrl.indexOf(":");
                
if (index != -1{
                    host 
= remainUrl.substring(0, index);
                    port 
= remainUrl.substring(index + 1);
                }
 else {
                    host 
= remainUrl;
                    port 
= null;
                }

                String proxyHost 
= "10.0.0.172";
                String proxyPort 
= "80";
                String cnwapUrl 
= "http://" + proxyHost + ":" + proxyPort + path;
                conn 
= (HttpConnection) Connector.open(cnwapUrl);
                
if (port == null)
                    conn.setRequestProperty(
"X-Online-Host", host);
                
else
                    conn.setRequestProperty(
"X-Online-Host", host + ":" + port);
            }

            dis 
= conn.openDataInputStream();
            
// begin analyze db file
            dis.skip(0x50L);//RMS头 80个字节
            int recNum = dis.readInt();//xcb文件的节点数,4个字节
            rms1.openWriteStream();
            rms1.write(recNum);
            rms1.addRecord(rms1.saveStreamToByteArray());
            rms1.closeWriteStream();
            dis.skip(
0x1CL);//28个字节的废字节
            for (int i = 0; i < recNum; i++{
                
if (BookingMidlet.limitDownloadSpeed){
                    
try {
                        Thread.sleep(
1000);
                    }
 catch (Exception ex) {
                        
//
                    }

                }

                EWLScreen.instance.repaint();
                
//16个字节是节点头
                dis.readInt();//4个字节的当前节点的序号
                dis.readInt();//4个字节的废字节
                int occupied = dis.readInt();//4个字节表示当前节点所在内存大小
                int recsize = dis.readInt();//4个字节表示当前节点的实际大小
                byte recdata[] = new byte[recsize];
                dis.readFully(recdata);
                
                
if(BookingMidlet.DEBUG)
                    System.out.println(
"-----save rms data: "+recsize);
                
// 以下代码用以计算下载百分比
                precentstr = "" + (100 * DownPrecent(rms)) / (recNum + 0.01);
                precentstr 
= forMatString(precentstr);
                UIManager._instance.set_percent(precentstr, FocusID);
                EWLScreen.prompt2 
= precentstr;
                
////////////////////////////////////////////////////////////////////////
                rms.openWriteStream();
                rms.write(recdata);
                rms.addRecord(rms.saveStreamToByteArray());
                rms.closeWriteStream();
                
                
//保存节点后面的废字节,以便续传时使用
                int Wastebytes = occupied - recsize - 16;
                rms2.openWriteStream();
                rms2.write(Wastebytes);
                rms2.addRecord(rms2.saveStreamToByteArray());
                rms2.closeWriteStream();
                dis.skip(Wastebytes); 
// subtract rec header
            }


            UIManager._instance.removeDownloadingItem(item);
            UIManager._instance.openDownloaded();
            UIManager._instance.insertDownloaded(item);
        }
 catch (Exception e) {
            
if(BookingMidlet.DEBUG){
                System.out.println(
"-----中断下载。");
            }

//            UIManager.showAlert("下载失败!请删除后重新下载");
        }
 finally {
            Close();
        }

    }

    
    
public void downloadFileagain(String url){
        
try {
            
if (RMSRecorderIfno.exists("002_" + imageName + "_mgz"&& !item.isResume)
                RMSRecorderIfno.delete(
"002_" + imageName + "_mgz");
            rms 
= new RMSRecorderIfno();
            rms.open(
"002_" + imageName + "_mgz"true);
            
//
            rms2 = new RMSRecorderIfno();
            
if (RMSRecorderIfno.exists("002_" + imageName + "_byte"&& !item.isResume) {
                RMSRecorderIfno.delete(
"002_" + imageName + "_byte");
            }

            rms2.open(
"002_" + imageName + "_byte"true);
            
            
//以下代码用以断点续传
            rms1 = new RMSRecorderIfno();
            rms1.open(
"002_" + imageName + "_url"false);
            url 
= setValue(rms1);
            
////////////////////////////////////////////////////////////////////////////
            String precentstr = "0";// 下载进度的百分比
            precentstr = "" + (100 * DownPrecent(rms)) / (xcblength);
            precentstr 
= forMatString(precentstr);
            UIManager._instance.set_percent(precentstr, FocusID);
            
//S40_V3版本需通过cmwap才能下载
            if (!BookingMidlet.useProxy){
                conn 
= (HttpConnection)Connector.open(url);
            }
 else {
                String remainUrl 
= url.substring("http://".length());
                
int index = remainUrl.indexOf("/");
                String path 
= "";
                
if (index != -1{
                    path 
= remainUrl.substring(index);
                    remainUrl 
= remainUrl.substring(0, index);
                }

                String host 
= "";
                String port 
= "";
                index 
= remainUrl.indexOf(":");
                
if (index != -1{
                    host 
= remainUrl.substring(0, index);
                    port 
= remainUrl.substring(index + 1);
                }
 else {
                    host 
= remainUrl;
                    port 
= null;
                }

                String proxyHost 
= "10.0.0.172";
                String proxyPort 
= "80";
                String cnwapUrl 
= "http://" + proxyHost + ":" + proxyPort + path;
                conn 
= (HttpConnection) Connector.open(cnwapUrl);
                
if (port == null)
                    conn.setRequestProperty(
"X-Online-Host", host);
                
else
                    conn.setRequestProperty(
"X-Online-Host", host + ":" + port);
            }

            
//设置Range
            int skipNum = RmsSize(rms, rms2);
            
            
if (skipNum == 112{
                dis 
= conn.openDataInputStream();
                dis.skip(
0x50L);//RMS头 80个字节
                xcblength = dis.readInt();//xcb文件的节点数,4个字节
                rms1.openWriteStream();
                rms1.write(xcblength);
                rms1.setRecord(
2, rms1.saveStreamToByteArray());
                rms1.closeWriteStream();
                dis.skip(
0x1CL);//28个字节的废字节
            }
else{
                conn.setRequestProperty(
"RANGE""bytes=" + skipNum + "-");//断点续传
                dis = conn.openDataInputStream();
            }

            item.isResume 
= false;
            
int num = DownPrecent(rms);
            
for (int i = 0; i < xcblength - num; i++{
                
if (BookingMidlet.limitDownloadSpeed){
                    
try {
                        Thread.sleep(
1000);
                    }
 catch (Exception ex) {
                        
//
                    }

                }

                EWLScreen.instance.repaint();
                
//16个字节是节点头
                dis.readInt();//4个字节的当前节点的序号
                dis.readInt();//4个字节的废字节
                int occupied = dis.readInt();//4个字节表示当前节点所在内存大小
                int recsize = dis.readInt();//4个字节表示当前节点的实际大
                byte recdata[] = new byte[recsize];
                dis.readFully(recdata);

                rms.openWriteStream();
                rms.write(recdata);
                rms.addRecord(rms.saveStreamToByteArray());
                rms.closeWriteStream();

                precentstr 
= "" + (100 * DownPrecent(rms)) / (xcblength);
                precentstr 
= forMatString(precentstr);
                UIManager._instance.set_percent(precentstr, FocusID);

                
//保存节点后面的废字节,以便续传时使用
                int Wastebytes = occupied - recsize - 16;
                rms2.openWriteStream();
                rms2.write(Wastebytes);
                rms2.addRecord(rms2.saveStreamToByteArray());
                rms2.closeWriteStream();
                dis.skip(Wastebytes); 
// subtract rec header
            }


            UIManager._instance.removeDownloadingItem(item);
            UIManager._instance.openDownloaded();
            UIManager._instance.insertDownloaded(item);
        }
 catch (Exception e) {
            
if(BookingMidlet.DEBUG){
                System.out.println(
"-----中断下载。");
            }

            
//UIManager.showAlert("下载失败!请删除后重新下载");
        }
 finally {
            Close();
        }


    }


    
/**
     * 计算百分比
     * 
@param str
     * 
@return
     
*/

    
public static String forMatString(String str) {
        String values;
        
int index = str.indexOf(".");
        
if(index != -1){
            values 
= str.substring(0, index);
        }
else{
            values 
= str;
        }

        
return values;
    }


    
/**
     *  遍历RMS,得到当前记录个数
     * 
@param rms
     * 
@return
     
*/

    
public int DownPrecent(RMSRecorderIfno rms) {
        
int i = 0;
        
try {
            RecordEnumeration enu 
= null;
            
if (enu == null{
                enu 
= rms.rs.enumerateRecords(nullnullfalse);
            }

            
while (enu.hasNextElement()) {
                
try {
                    enu.nextRecordId();
                }
 catch (InvalidRecordIDException e) {
                    e.printStackTrace();
                }

                i
++;
            }

        }
 catch (RecordStoreNotOpenException e) {
            e.printStackTrace();
        }

        
return i;
    }


    
/**
     *  遍历RMS,计算当前记录的长度
     * 
@param rms
     * 
@param rms1
     * 
@return
     
*/

    
public int RmsSize(RMSRecorderIfno _rms, RMSRecorderIfno _rms2) {
        
int i = 112;
        
try {
            RecordEnumeration enu 
= null;
            
if (enu == null{
                enu 
= _rms.rs.enumerateRecords(nullnullfalse);
            }

            
while (enu.hasNextElement()) {
                
try {
                    i 
+= enu.nextRecord().length;
                    i 
+= 16;
                }
 catch (InvalidRecordIDException e) {
                    e.printStackTrace();
                }
 catch (RecordStoreException e) {
                    e.printStackTrace();
                }

            }

        }
 catch (RecordStoreNotOpenException e) {
            e.printStackTrace();
        }

        i 
= i + sikpSize(_rms2);
        
return i;
    }


    
/**
     *  遍历RMS,计算rms中各个节点后跳过的节点大小
     * 
@param rms
     * 
@return
     
*/

    
public int sikpSize(RMSRecorderIfno _rms2) {
        
int len = 0;
        
try {
            RecordEnumeration enu 
= null;
            
if (enu == null{
                enu 
= _rms2.rs.enumerateRecords(nullnullfalse);
            }

            
while (enu.hasNextElement()) {
                
try {
                    len 
+= bytesToInt(enu.nextRecord());
                }
 catch (InvalidRecordIDException e) {
                    e.printStackTrace();
                }
 catch (RecordStoreException e) {
                    e.printStackTrace();
                }

            }

        }
 catch (RecordStoreNotOpenException e) {
            e.printStackTrace();
        }

        
        
return len;
    }


    
/**
     * byte转int
     * 
@param bytes
     * 
@return
     
*/

    
public static int bytesToInt(byte[] bytes) {
        
int result = 0;
        
for (int i = 0; i < bytes.length; i++{
            result 
<<= 8;
            result 
|= (bytes[i] & 0xff); //此处忽略byte的符号位   
        }

        
return result;
    }

    
    
private String setValue(RMSRecorderIfno rms){
        String url 
= "";
        RecordEnumeration enu 
= null;
        
if (enu == null{
            
try {
                enu 
= rms.rs.enumerateRecords(nullnullfalse);
            }
 catch (RecordStoreNotOpenException e) {
                e.printStackTrace();
            }

            
int i = 0;
            
while (enu.hasNextElement()) {
                
try {
                    i 
= enu.nextRecordId();
                    
if (i == 1{
                        url 
= new String(rms.getRecord(i));
                    }
 else if (i == 2{
                        xcblength 
= bytesToInt(rms.getRecord(i));
                    }

                }
 catch (InvalidRecordIDException e) {
                    e.printStackTrace();
                }

            }

        }

        
return url;
    }

}

posted on 2010-02-25 14:58 骑猪闯天下 阅读(342) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: