文件的简单断点续传

文件的断点续传是指我们在下载时需要进行暂停或者网络断开等一系列事件所做的暂停操作,当我们再次进行操作的时候,将文件进行再次下载时,原先已经完成的部分就会连接上,继续下载

Main方法代码:

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.tv)
    TextView tv;
    private String path;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        initModel();
    }

    private void initModel() {
        //进行读取文件的绝对路径
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            File externalStorageDirectory = Environment.getExternalStorageDirectory();
            String absolutePath = externalStorageDirectory.getAbsolutePath();
            //拼接至我们内存中下的一个文件夹
            path = absolutePath + "/李大本事/";
            //将我们要保存至的路径传到网络请求上
            Model.getInstance().initDownLoad(path);
            //接口回传
            Model.getInstance().setModel(new ModelInterface() {
                @Override
                public void FileSuccess() {

                }

                @Override
                public void FileFailed() {

                }
                //将进度通过给TextView的形式展示出来
                @Override
                public void Progress(final long progress) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    tv.setText(progress+"");
                                }
                            });
                        }
                    });
                }
            });
        }
    }

    //点击按钮
    @OnClick({R.id.btn_action, R.id.btn_stop})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_action:
                Model.getInstance().initStart("http://dlsw.baidu.com/sw-search-sp/soft/4b/17170/Install_WLMessenger14.0.8117.416.1393467029.exe");
                break;
            case R.id.btn_stop:
                Model.getInstance().initStop();
                break;
        }
    }
}

网络请求的代码:

public class Model {
    private static volatile Model instance;
    private String absolutePath;
    private File file;
    private long startPostion;
    private Call call;

    private Model(){}
    public static Model getInstance(){
        if(instance == null){
            synchronized (Model.class){
                if(instance == null){
                    instance = new Model();
                }
            }
        }
        return instance;
    }

    private ModelInterface modelInterface;
    public void setModel(ModelInterface modelInterface){
        this.modelInterface = modelInterface;
    }
    //判断地址是否存在
    public void initDownLoad(String path){
        File file = new File(path);
        //如果父路径不存在,就创建父路径
        if(!file.getParentFile().exists()){
            file.getParentFile().mkdir();
        }
        //如果子文件不存在,就创建
        if(!file.exists()){
            file.mkdir();
        }
        absolutePath = file.getAbsolutePath();
        Log.e("----得到的地址:",absolutePath);
    }
    //点击开始做的操作,传递一个地址,用来拼接地址,并访问网络
    public void initStart(String url){
        //判断地址是否存在
        if(TextUtils.isEmpty(url)){
            return;
        }
        //判断地址中是否包含后缀名
        if(url.contains(".")){
            //取出包含点的后缀名
            String substring_one = url.substring(url.lastIndexOf("."));
            Log.e("----得到的地址文件名:",substring_one);
            //判断是否有/
            if(url.contains("/")){
                String substring_two = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
                Log.e("----得到的地址文件名:",substring_two);
                //将完全地址拼接上
                String allPath = substring_two + substring_one;
                //创建一个文件路径
                file = new File(absolutePath, allPath);
                Log.e("----得到的地址:",absolutePath+"--"+allPath);
            }
        }
        //用来记录当前的下载进度
        startPostion = 0;
        //如果当前文件已存在,就将文件长度赋值给初始值
        if(file.exists()){
            startPostion = file.length();
        }
        //创建网络请求
        OkHttpClient okHttpClient = new OkHttpClient();
        Log.e("----当前文件大小",startPostion+"");
        Request range = new Request.Builder()
                //判断从网络读取的位置从文件大小开始
                .addHeader("RANGE", "bytes=" + startPostion + "-")
                .url(url)
                .build();
        call = okHttpClient.newCall(range);
        call.enqueue(new Callback() {

            private long bodyLength;

            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                ResponseBody body = response.body();
                //文件的大小加上之前文件的大小,才能成为100%
                bodyLength = body.contentLength()+startPostion;
                InputStream inputStream = body.byteStream();
                byte[] bts = new byte[2048];
                int len = 1;
                long num = startPostion;
                while((len = inputStream.read(bts,0,bts.length))!=-1){
                    //创建一个方法,可以在文件下的任意地方进行读写
                    RandomAccessFile rw = new RandomAccessFile(file, "rw");
                    //让文件从原先大小的位置开始操作
                    rw.seek(num);
                    //将读取的文件进行写入
                    rw.write(bts,0,len);
                    num += len;
                    modelInterface.Progress(num*100/bodyLength);
                }
                inputStream.close();
                modelInterface.FileSuccess();
            }
        });
    }
    //点击暂停的操作
    public void initStop(){
        //判断Call对象是否正在运行而且存在
        if(call.isExecuted()&&call!=null){
            call.cancel();
        }
    }
}

网络请求的接口:

public interface ModelInterface {
    void FileSuccess();
    void FileFailed();
    void Progress(long progress);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值