java和Android文件下载断点续传和图片下载代码实现,可直接复制简单实现

本文介绍了一种基于HTTP协议的断点续传下载方法,通过添加Range头部字段支持从上次断开的位置继续下载文件。文章详细展示了如何利用Java进行断点续传下载的实现过程,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明出处,下载源文件可以点击http://download.youkuaiyun.com/download/zhanghao_hulk/8628505


package com.example.filetest;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;

/*import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;*/
import org.apache.http.Header;
import org.apache.http.HttpException;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.text.TextUtils;
import android.util.Log;

public class NetDownlodUtils {

    public interface DownloadCallback {
        void onStart(long downloaded, long fileSize);
        void onProgress(int progress, long dowloaded, long fileSize);
        void OnFinished(boolean completed, long fileSize, String remark);
    }
    private final static int TIMEOUT_CONNECTION = 15 * 1000;
    private final static int TIMEOUT_SOCKET = 15 * 1000;
    private final static int RETRY_TIME = 2;
    public static final String UTF_8 = "UTF-8";
    private static final String TAG = "NetDownlodUtils";

    /**
     * 下载文件,实现断点续传,添加range到header
     * @param url
     * @param destFile
     * @return
     */
    public static File downloadBreakpointContinuingly(String url, File destFile, DownloadCallback cb) {
        RandomAccessFile raf = null;
        InputStream input = null;
        long fileSize = 0;
        String errorMsg = null;
        try {
            Log.d(TAG, "Starting download file : " + destFile + " , url: " + url);
            new File(destFile.getParent()).mkdirs();
            fileSize = getDownloadFileSize(url);
            destFile.createNewFile();
            raf = new RandomAccessFile(destFile, "rw");
            long downloaded = raf.length();
            if(cb != null) {
                cb.onStart(downloaded, fileSize);
            }
            Log.d(TAG, "should download rest filesize: " + (fileSize - downloaded));
            HttpGet get = getHttpGet(url, raf.length(), -1);
            HttpResponse response = getHttpClient().execute(get);

            int code = response.getStatusLine().getStatusCode();
            Log.d(TAG, "download file return code: " + code);

            if (code == HttpStatus.SC_PARTIAL_CONTENT) {
                raf.seek(destFile.length());
                errorMsg = "HttpStatus.SC_PARTIAL_CONTENT";
            } else if (code == HttpStatus.SC_NOT_FOUND) {
                errorMsg = "HttpStatus.SC_NOT_FOUND";
                return null;
            } else if (code != HttpStatus.SC_OK) {
                errorMsg = "code != HttpStatus.SC_OK !! code= " + code;
                return null;
            }
            long restFileSize = response.getEntity().getContentLength();
            Log.d(TAG, "try download rest file size=" + restFileSize);
            // TODO 最好先检查存储空间,面的写数据失败

            input = response.getEntity().getContent();
            byte data[] = new byte[4096];
            int count;
            while ((count = input.read(data)) != -1) {
                raf.write(data, 0, count);
                int progress = fileSize == 0 ? 0 : (int) (raf.length() * 100 / fileSize);
                if(cb != null) {
                    cb.onProgress(progress, raf.length(), fileSize);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.w(TAG, e.toString());
        } finally {
            try {
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                raf.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if(cb != null) {
                cb.OnFinished(true, fileSize, errorMsg);
            }
        }
        return destFile;
    }

    /**
     * 实现断点续传,添加range到header
     * 注意点: range区间不能指定end,否则在某些情况下(如阿里云服务器)不生效),不指定end绘制解把文件读完整
     * @param url
     * @param start
     * @return
     */
    protected static HttpGet getHttpGet(String url, long start, long end) {
        HttpGet httpGet = new HttpGet(url);
        if(start >= 0) {
            StringBuffer range = new StringBuffer("bytes=" + start + "-");
            if(end > start) {
                range.append(end);
            }
            Header headerRange = new BasicHeader("Range", range.toString());
            Log.d(TAG, "range header: " + headerRange);
            httpGet.addHeader(headerRange);
        }
        return httpGet;
    }
    /**
     * 如果尚未知道文件的下载大小,则先主动获取一下
     */
    private static long getDownloadFileSize(String url) {
        long fileSize = 0;
        try {
            HttpGet get = getHttpGet(url, 0, -1);
            fileSize = getHttpClient().execute(get).getEntity().getContentLength();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileSize;
    }

    public static NetworkInfo getNetworkInfo(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        return networkInfo;
    }

    public static boolean isNetConnected(Context context) {
        if (context != null) {
            NetworkInfo ni = getNetworkInfo(context);
            return ni != null && ni.isAvailable() && ni.isConnected();
        }
        return false;
    }
    
    /**
     * get net type name: cmwap/cmnet/wifi/uniwap/uninet/ctnet/ctwap
     * @param context
     * @return
     */
    public static String getNetWorkTypeName(Context context) {
        String networkType = null;
        try {
            NetworkInfo networkInfo = getNetworkInfo(context);// NULL
            if (networkInfo != null && networkInfo.isAvailable()) {
                String typeName = networkInfo.getTypeName(); // MOBILE/WIFI
                if (!"MOBILE".equalsIgnoreCase(typeName)) {
                    networkType = typeName;
                } else {
                    networkType = networkInfo.getExtraInfo(); // cmwap/cmnet/wifi/uniwap/uninet
                    if (networkType == null) {
                        networkType = typeName + "#[]";
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return networkType;
    }

    public static Bitmap getNetBitmap(String url) {
        return downloadNetBitmap(url);
    }

    public static InputStream downloadNetStream(String url) {
        InputStream input = null;
        int retryTimes = 0;
        do {
            try {
                HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
                con.setDoInput(true);
                con.connect();
                input = con.getInputStream();
                int maxSize = con.getContentLength();
                Log.i(TAG, "maxSize== " + maxSize);
                return input;
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (input == null) {
                retryTimes++;
                if (retryTimes < RETRY_TIME) {
                    try {
                        Thread.sleep(1000);
                        Log.i(TAG, "downloadNetStream retryTimes= " + retryTimes);
                    } catch (InterruptedException e1) {
                    }
                    continue;
                }
            }
        } while (retryTimes < RETRY_TIME);
        return input;
    }
    
    public static Bitmap downloadNetBitmap(String url) {
        Bitmap bitmap = null;
        InputStream inStream = null;
        try {
            inStream = downloadNetStream(url);
            if (inStream != null) {
                bitmap = BitmapFactory.decodeStream(inStream);
            }
        } catch (OutOfMemoryError e3) {
            e3.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(inStream != null) {
                try {
                    inStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return bitmap;
    }

    public static void saveStreamToFiles(Context context, InputStream is,
            String fileName) {
        if (is == null)
            return;
        byte[] buffer = new byte[1024];
        int len = -1;
        try {
            FileOutputStream bos = context.openFileOutput(fileName,
                    Context.MODE_PRIVATE);
            while ((len = is.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
                bos.flush();
            }
            if (bos != null) {
                bos.close();
            }
            is.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Bitmap getHttpBitmap(String url) {
        HttpClient httpClient = null;
        HttpGet httpGet = null;
        InputStream inStream = null;
        Bitmap bmp = null;
        int retryTimes = 0;
        try {
            do {
                try {
                    httpClient = getHttpClient();
                    httpGet = getHttpGetMethod(url, null, null);
                    HttpResponse res = httpClient.execute(httpGet);
                    int statusCode = res.getStatusLine().getStatusCode();
                    if (statusCode != HttpStatus.SC_OK) {
                        throw new Exception("error statusCode= " + statusCode);
                    }
                    inStream = res.getEntity().getContent();
                    bmp = BitmapFactory.decodeStream(inStream);
                    inStream.close();
                    break;
                } catch (OutOfMemoryError e3) {
                    e3.printStackTrace();
                } catch (HttpException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (bmp == null) {
                    retryTimes++;
                    if (retryTimes < RETRY_TIME) {
                        try {
                            Thread.sleep(1000);
                            Log.w(TAG, "downloadBitmap retryTimes= " + retryTimes);
                        } catch (InterruptedException e3) {
                        }
                        continue;
                    }
                }
            } while (retryTimes < RETRY_TIME);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            httpClient = null;
        }
        return bmp;
    }

    public static HttpClient getHttpClient() {
        BasicHttpParams params = new BasicHttpParams();
        // 设置连接及响应超时时间(s)
        HttpConnectionParams.setConnectionTimeout(params, TIMEOUT_CONNECTION);
        HttpConnectionParams.setSoTimeout(params, TIMEOUT_SOCKET);

        
        SchemeRegistry schemeRegistry = new SchemeRegistry();
        schemeRegistry.register(new Scheme("http", PlainSocketFactory
                .getSocketFactory(), 80));
        
        SSLSocketFactory sslSocketFactory = null;
        try {
            // 不使用已存在的keyStore,即时运算证书,传入null即可
            sslSocketFactory = new SSLSocketFactory(null);
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }

        schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));
        ClientConnectionManager cm = new ThreadSafeClientConnManager(params,
                schemeRegistry);
        return new DefaultHttpClient(cm, params);
    }

    private static HttpGet getHttpGetMethod(String url, String cookie,
            String userAgent) {
        HttpGet httpGet = new HttpGet(url);
        httpGet.addHeader("Connection", "Keep-Alive");
        httpGet.addHeader("Cookie", cookie);
        httpGet.addHeader("User-Agent", userAgent);
        return httpGet;
    }

    /**
     * get file name according to url
     *
     * @param url
     * @return
     */
    public static String getFileName(String url) {
        if (TextUtils.isEmpty(url))
            return "";
        return url.substring(url.lastIndexOf(File.separator) + 1);
    }

    /**
     * Java文件操作 获取不带扩展名的文件名
     *
     * @param fileNameOrPath
     * @return
     */
    public static String getFileNameNoEx(String fileNameOrPath) {
        if ((fileNameOrPath != null) && (fileNameOrPath.length() > 0)) {
            int dot = fileNameOrPath.lastIndexOf('.');
            if ((dot > -1) && (dot < (fileNameOrPath.length()))) {
                return fileNameOrPath.substring(0, dot);
            }
        }
        return fileNameOrPath;
    }

    public static int getType(Context context) {
        int netType = -1;
        NetworkInfo networkInfo = getNetworkInfo(context);
        if (networkInfo == null) {
            return netType;
        }
        netType = networkInfo.getType();
        return netType;
    }
    
    public static boolean isMobileDataMode(Context context) {
        return getType(context) == ConnectivityManager.TYPE_MOBILE;
    }
}


转载请注明出处

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值