从资源上传okhttp的二进制文件

 啊4呀么啊4呀 发布于 2022-12-27 12:56

我需要使用okhttp将apk中捆绑的二进制文件上传到服务器.使用urlconnection,您只需获取资产的输入流,然后将其放入您的请求中.但是,okhttp只提供上传字节数组,字符串或文件的选项.由于您无法获取apk中捆绑的资产的文件路径,因此将文件复制到本地文件目录的唯一选项(我宁愿不这样做)然后将文件提供给okhttp?有没有办法简单地使用assetinputstream直接向Web服务器发出请求?

编辑:我使用了接受的答案,但我没有创建一个静态实用程序类,而只是将子类化为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的内部实现

1 个回答
  • 您可能无法使用库直接执行此操作,但您可以创建一个小实用程序类来为您执行此操作.然后,您可以在任何需要的地方重复使用它.

    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);
                    }
                }
            };
        }
    }
    

    然后就这样简单地使用它

    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());    
    

    此示例代码基于此代码.替换Assets文件名和MediaType您自己的名称.

    2022-12-27 12:58 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有