Android之文件断点续传

之前在项目中做过Android端文件断点下载模块,采用RandomAccessFile保存临时文件,通过对上传文件的物理路径path进行MD5加密判断是否为断点文件,如果是则进行断点下载,最后处理好下载进度,整个业务逻辑很简单,demo请参考https://github.com/MrZhousf/OkHttp3 ,这里就不再赘述了。

那么本篇要说的是Android端怎么处理断点上传文件,首先我们要明确几点需要解决的问题:

1、断点谁来保存:是服务端保存还是Android端保存?

2、断点如何保存

3、断点上传进度如何处理

首先对于断点谁来保存的问题,个人建议是服务端保存。倘若让Android端保存文件断点会出现许多不可预料的问题,比如:上传过程中出现中断(网络状况原因或超时、流处理异常等),这时候Android端保存的断点为写入pipe管道的字节数,然后服务器接收到的字节数不一定和Android端一致。鉴于Android端对断点保存的准确性和可靠性考虑,让服务器端保存断点。这也无疑给服务端带来一些复杂度,服务端要针对断点和临时文件的处理编写一套完整并稳定的功能块也需要一定的考虑。

至于断点如何保存是服务端需要考虑的问题,但是我们这里还是需要讨论下。从事服务端开发的同志都习惯采用数据库来处理一些数据业务逻辑,这里我也建议采用数据库记录断点,不过需要对表的设计、主键、索引处理好,这样提高读取的速率。对上传文件结合上传属性生成唯一的标识(可采用UUID)作为主键或索引,针对上传完毕的数据及时清理,防止数据表的数据越来越大。若不采用数据库记录断点,那就像断点下载那样将上传的信息通过一定规则反映在临时文件名或路径中,但这样的缺点是需要遍历磁盘获取断点文件,这个过程的开销不能小觑。

那么最后一个问题,断点上传的进度如何处理。这个问题很客观,例如Android端现在上传了一个断点文件,文件共10MB,已经上传了5MB,现在进行断点上传时,进度条总长度应该的10MB,起始点是5MB才对。这种需求处理起来也不是一件容易的事情,好在上面的demo框架中对文件上传的进度进行了灵活的扩展可以支持该需求。

其实对于断点上传文件我个人认为阿里云的分块上传方法挺不错的,感兴趣的同志可以了解下,但是由于工作环境的种种原因,笔者只能采用这个比较基本的方法了。

Android上传文件逻辑:读取数据库检查该文件是否是断点文件,否则直接上传文件并写入数据库上传文件的信息,是则请求服务端获取断点,上传断点文件。上传成功后删除数据库记录。

下面是一些逻辑和代码片段,具体的请参考demo:

1、读取数据库判定是否断点上传文件

2、请求服务端获取文件断点breakPoint

3、截取断点文件:

//filePath为原文件路径,该方法返回断点截取后的文件地址

String path = FileUtil.copyFile(breakPoint,0,filePath);
4、上传断点文件:

HttpInfo info = HttpInfo.Builder()
                .setUrl(url)
                .addUploadFile("uploadFile",path,new ProgressCallback(){
                    @Override
                    public void onProgressMain(int percent, long bytesWritten, long contentLength, boolean done) {
                        int breakPercent = (int) ((100 * (bytesWritten+breakPoint)) / (contentLength+breakPoint));
                        uploadProgress.setProgress(breakPercent);
                        LogUtil.d(TAG, "上传进度:" + breakPercent);
                    }

                    @Override
                    public void onResponseMain(String filePath, HttpInfo info) {
                        tvResult.setText(info.getRetDetail());
                    }
                })
                .build();
        OkHttpUtil.getDefault(this).doUploadFileAsync(info);
注意上传进度条的控制,根据断点重新计算上传进度。

5、上传完成后,删除数据库的文件记录和临时文件

至此,简单的断点上传功能已完成,如果后期有机会笔者再来实现分块上传文件的方案。


猜你喜欢

转载自blog.csdn.net/zsf442553199/article/details/69944574