package com.hjq.http.model; import com.hjq.http.EasyLog; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.FileNameMap; import java.net.URLConnection; import java.net.URLEncoder; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.RequestBody; import okio.Buffer; import okio.BufferedSink; import okio.Okio; import okio.Source; /** * author : Android 轮子哥 * github : https://github.com/getActivity/EasyHttp * time : 2019/12/14 * desc : 上传文件请求 */ public final class UpdateBody extends RequestBody { public static final MediaType MEDIA_TYPE = MediaType.parse("application/octet-stream"); /** * 上传源 */ private final Source mSource; /** * 内容类型 */ private final MediaType mMediaType; /** * 内容名称 */ private final String mName; /** * 内容大小 */ private final long mLength; public UpdateBody(File file) throws FileNotFoundException { this(Okio.source(file), guessMimeType(file.getName()), file.getPath(), file.length()); } public UpdateBody(InputStream inputStream, String name) throws IOException { this(Okio.source(inputStream), MEDIA_TYPE, name, inputStream.available()); } public UpdateBody(Source source, MediaType type, String name, long length) { mSource = source; mMediaType = type; mName = name; mLength = length; } @Override public MediaType contentType() { return mMediaType; } @Override public long contentLength() { return mLength; } @Override public void writeTo(BufferedSink sink) throws IOException { Buffer buffer = new Buffer(); long totalLength = contentLength(); long updateLength = 0; long readCount; while ((readCount = mSource.read(buffer, 2048)) != -1) { sink.write(buffer, readCount); updateLength += readCount; EasyLog.print(mName + " 正在上传" + ",文件总字节:" + totalLength + ",已上传字节:" + updateLength); } } /** * 根据文件名获取 MIME 类型 */ public static MediaType guessMimeType(String fileName) { FileNameMap fileNameMap = URLConnection.getFileNameMap(); // 解决文件名中含有#号异常的问题 fileName = fileName.replace("#", ""); String contentType = fileNameMap.getContentTypeFor(fileName); if (contentType == null) { return MEDIA_TYPE; } MediaType type = MediaType.parse(contentType); if (type == null) { type = MEDIA_TYPE; } return type; } /** * 根据 File 对象创建一个流媒体 */ public static MultipartBody.Part createPart(String key, File file) { if (file.exists() && file.isFile()) { try { // 文件名必须不能带中文,所以这里要编码 return MultipartBody.Part.createFormData(key, URLEncoder.encode(file.getName()), new UpdateBody(file)); } catch (FileNotFoundException e) { EasyLog.print(e); } } else { EasyLog.print("文件不存在,将被忽略上传:" + key + " = " + file.getPath()); } return null; } /** * 根据 InputStream 对象创建一个流媒体 */ public static MultipartBody.Part createPart(String key, InputStream inputStream) { try { return MultipartBody.Part.createFormData(key, null, new UpdateBody(inputStream, key)); } catch (IOException e) { EasyLog.print(e); } return null; } }