上传二进制文件与资源okhttp [英] Upload binary file with okhttp from resources
问题描述
我需要使用okhttp捆绑在APK二进制文件上传到服务器。使用的URLConnection,你可以简单地得到一个InputStream为一项资产,然后将其写入您的要求。然而,okhttp只给你上传字节数组,字符串或文件的选项。因为你不能获取文件路径捆绑在APK的资产,是把文件复制到本地文件目录的唯一选择(我宁愿不这样做),然后给okhttp文件?请问有没有办法直接使用assetinputstream到Web服务器简单地提出一个要求?
I need to upload a binary file bundled in an apk to a server using okhttp. Using urlconnection, you can simply get an inputstream to an asset and then put that into your request. However, okhttp only gives you the option of uploading byte arrays, strings, or files. Since you can't get a file path for an asset bundled in the apk, is the only option to copy the file to the local file directory (I'd rather not do that) and then give the file to okhttp? Is there no way to simply make a request using the assetinputstream directly to the web server?
编辑:我使用,但不是做一个静态的工具类,我只是子类RequestBody接受的答案
I used the accepted answer but instead of making a static utility class I simply subclassed RequestBody
public class InputStreamRequestBody extends RequestBody {
private InputStream inputStream;
private MediaType mediaType;
public static RequestBody create(final MediaType mediaType, final InputStream inputStream) {
return new InputStreamRequestBody(inputStream, mediaType);
}
private InputStreamRequestBody(InputStream inputStream, MediaType mediaType) {
this.inputStream = inputStream;
this.mediaType = mediaType;
}
@Override
public MediaType contentType() {
return mediaType;
}
@Override
public long contentLength() {
try {
return inputStream.available();
} catch (IOException e) {
return 0;
}
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
Source source = null;
try {
source = Okio.source(inputStream);
sink.writeAll(source);
} finally {
Util.closeQuietly(source);
}
}
}
我的这种方法只关注inputstream.available()的内容长度的不可靠性。静态构造函数是匹配okhttp内部实施
My only concern with this approach is the unreliability of inputstream.available() for content-length. The static constructor is to match okhttp's internal implementation
推荐答案
您可能无法直接使用该库做,但你可以创建一个会为你做一个小工具类。然后,您可以简单地重新使用它无处不在,你需要它。
You might not be able to do it directly using the library but you could create a little utility class which would do it for you. You could then simply re-use it everywhere you need it.
public class RequestBodyUtil {
public static RequestBody create(final MediaType mediaType, final InputStream inputStream) {
return new RequestBody() {
@Override
public MediaType contentType() {
return mediaType;
}
@Override
public long contentLength() {
try {
return inputStream.available();
} catch (IOException e) {
return 0;
}
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
Source source = null;
try {
source = Okio.source(inputStream);
sink.writeAll(source);
} finally {
Util.closeQuietly(source);
}
}
};
}
}
然后,只需使用它像这样
Then simply use it like so
OkHttpClient client = new OkHttpClient();
MediaType MEDIA_TYPE_MARKDOWN
= MediaType.parse("text/x-markdown; charset=utf-8");
InputStream inputStream = getAssets().open("README.md");
RequestBody requestBody = RequestBodyUtil.create(MEDIA_TYPE_MARKDOWN, inputStream);
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(requestBody)
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful())
throw new IOException("Unexpected code " + response);
Log.d("POST", response.body().string());
这个例子code是根据<一href="https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/com/squareup/okhttp/recipes/PostFile.java">this code。替换资产
文件名和的MediaType
用你自己的。
This example code was based on this code. Replace the Assets
file name and the MediaType
with your own.
这篇关于上传二进制文件与资源okhttp的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!