伪原创网站源码( FileRequestBody类完整源码,代码如下:小结断点上传,客户端 )
优采云 发布时间: 2022-02-01 01:16伪原创网站源码(
FileRequestBody类完整源码,代码如下:小结断点上传,客户端
)
//为简化阅读,已省略部分代码
public class FileRequestBody extends RequestBody {
private final File file;
private final long skipSize; //断点位置
private final MediaType mediaType;
public FileRequestBody(File file, long skipSize, @Nullable MediaType mediaType) {
this.file = file;
this.skipSize = skipSize;
this.mediaType = mediaType;
}
@Override
public long contentLength() throws IOException {
return file.length() - skipSize;
}
@Override
public void writeTo(@NotNull BufferedSink sink) throws IOException {
InputStream input = null;
Source source = null;
try {
input = new FileInputStream(file);
if (skipSize > 0) {
input.skip(skipSize); //跳到断点位置
}
source = Okio.source(input);
sink.writeAll(source);
} finally {
OkHttpCompat.closeQuietly(source, input);
}
}
}
为方便阅读,上面省略了部分源码,FileRequestBody类的完整源码
有了 FileRequestBody 类,我们只需要传入一个断点位置,剩下的工作和正常的文件上传一样。接下来,直接进入代码实现。
二、代码实现2.1 获取断点位置
首先,服务器需要提供一个接口,通过userId查找用户尚未上传和完成的任务列表。代码如下:
RxHttp.get("/.../getToUploadTask")
.add("userId", "88888888")
.asList()
.subscribe({
//成功回调,这里通过 it 拿到 List
}, {
//异常回调
});
ToUploadTask 类如下:
//待上传任务
data class ToUploadTask(
val md5: String, //文件的md5,用于验证文件的唯一性
val filePath: String, //文件在客户端的绝对路径
val skipSize: Long = 0 //断点位置
)
注意:这两个参数md5、filePath需要客户端在上传文件的时候传给服务端,用来校验文件,防止文件乱码
2.2 断点上传
有了要上传的任务,客户端就可以进行断点上传操作。OkHttp 代码如下:
fun uploadFile(uploadTask: ToUploadTask) {
//1.校验文件是否存在
val file = File(uploadTask.filePath)
if (!file.exists() && !file.isFile) return
//2.校验文件的 md5 值
val fileMd5 = FileUtils.getFileMD5ToString(file)
if (!fileMd5.equals(uploadTask.md5)) return
//3.构建请求体
val fileRequestBody = FileRequestBody(file, uploadTask.skipSize, BuildUtil.getMediaType(file.name))
val multipartBody = MultipartBody.Builder()
.addFormDataPart("userId", "88888888")
.addFormDataPart("md5", fileMd5)
.addFormDataPart("filePath", file.absolutePath)
.addFormDataPart("file", file.name, fileRequestBody) //添加文件body
.build()
//4.构建请求
val request = Request.Builder()
.url("/.../uploadFile")
.post(multipartBody)
.build()
//5.执行请求
val okClient = OkHttpClient.Builder().build()
okClient.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
//异常回调
}
override fun onResponse(call: Call, response: Response) {
//成功回调
}
})
}
FIleUtils 源码、BuildUtil 源码
当然,考虑到很少有人直接使用OkHttp,这里也贴出RxHttp的实现代码。这很简单。您只需要构建一个UpFile对象,就可以轻松监控上传进度。代码如下:
fun uploadFile(uploadTask: ToUploadTask) {
//1.校验文件是否存在
val file = File(uploadTask.filePath)
if (!file.exists() && !file.isFile) return
//2.校验文件的 md5 值
val fileMd5 = FileUtils.getFileMD5ToString(file)
if (!fileMd5.equals(uploadTask.md5)) return
val upFile = UpFile("file", file, file.name, uploadTask.skipSize)
//3.直接上传
RxHttp.postForm("/.../uploadFile")
.add("userId", "88888888")
.add("md5", fileMd5)
.add("filePath", file.absolutePath)
.addFile(upFile)
.upload(AndroidSchedulers.mainThread()) {
//上传进度回调
}
.asString()
.subscribe({
//成功回调
}, {
//异常回调
})
}
概括
断点上传与普通文件上传相比,在客户端多了一个断点设置。大多数工作负载都在服务器端。服务器端不仅需要处理文件的拼接逻辑,还需要记录尚未上传的任务并通过接口。暴露给客户。
在这里,我还分享了一份学习PDF+架构视频+面试文档+源码笔记,高级架构技术高级脑图,Android开发面试题目资料,老板亲自整理的高级高级架构资料收录
这些是我在业余时间会一遍又一遍地阅读的好材料。对近年来大厂访谈的高频知识点进行了详细讲解。相信它可以有效地帮助你掌握知识,理解原理,帮助你在日后得到一个好的答案。
当然,你也可以用它来检查差距,提高你的竞争力。
真心希望对大家有所帮助,安卓任重而道远,大家互相鼓励!
需要的可以私信我【进阶】获取