输入流开始读取时,输出流开始写入

时间:2018-08-29 06:39:41

标签: java web io jersey-client

我想通过http发送一个大对象(比如说4G)。

我们有一个自定义序列化程序,该对象将对象写入OutputStream。此刻,我们将对象写入磁盘,并将该文件用于请求的输入流。

类似以下几行:

private static Response sendObject(Object bigObject) throws IOException {
  File tempFile = File.createTempFile("x", "y");
  OutputStream out = new FileOutputStream(tempFile);
  CustomSerializer.serialize(bigObject, out);
  out.close();

  WebTarget resource = service.path("data");

  FormDataMultiPart multiPartEntity = new FormDataMultiPart();

  InputStream inputStream = new FileInputStream(tempFile);
  StreamDataBodyPart streamBodyPart = new StreamDataBodyPart(
        "data",
        inputStream,
        "data",
        MediaType.APPLICATION_OCTET_STREAM_TYPE);

  MultiPart multiPart = multiPartEntity.bodyPart(streamBodyPart);
  return resource.request(MediaType.APPLICATION_JSON_TYPE)
        .post(Entity.entity(multiPart, multiPart.getMediaType()));
 }

我们节省了一些内存,因为我们没有序列化到内存中的字节数组。真好。但是我可以在不写入磁盘的情况下保存内存吗?

您可以直接写入输入流而不重写CustomSerializer吗?

当输入流读入请求时,您可以直接写它吗?

-

有点难以解释,但是我想我正在寻找类似以下伪代码的内容:

private static Response sendObject(Object bigObject) throws IOException {
  WebTarget resource = service.path("data");

  FormDataMultiPart multiPartEntity = new FormDataMultiPart();

  // A type of stream I don't know if exist
  OutputStream outIn = new OutputInputStream() {
     public void openInputStream() {
        CustomSerializer.serialize(bigObject, this);
     }
  };
  StreamDataBodyPart streamBodyPart = new StreamDataBodyPart(
        "data",
        outIn.getInputStream(),
        "data",
        MediaType.APPLICATION_OCTET_STREAM_TYPE);

  MultiPart multiPart = multiPartEntity.bodyPart(streamBodyPart);
  return resource.request(MediaType.APPLICATION_JSON_TYPE)
        .post(Entity.entity(multiPart, multiPart.getMediaType()));
} 

1 个答案:

答案 0 :(得分:1)

您可以使用StreamingOutput并使用CustomSerializer来写入提供的OutputStream

StreamingOutput entity = new StreamingOutput() {
    @Override
    public void write(OutputStream out)
            throws IOException, WebApplicationException {

        CustomSerializer.serialize(bigObject, out);
    }
};

write()方法将由Jersey调用,使您有机会直接写入响应实体流。

然后只使用FormDataBodyPart

BodyPart bigPart = new FormDataBodyPart(
        "data", entity, MediaType.APPLICATION_OCTET_STREAM_TYPE);
MultiPart multiPart = new FormDataMultiPart().bodyPart(bigPart);