Исходящий поток начинает писать, когда входной поток начинает читать - PullRequest
0 голосов
/ 29 августа 2018

Я хочу отправить большой объект (скажем, 4G) через http.

У нас есть собственный сериализатор, который записывает объект в 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 голосов
/ 29 августа 2018

Вы можете использовать StreamingOutput и использовать CustomSerializer для записи в предоставленный OutputStream

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

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

Метод write() будет вызываться Джерси, что даст вам возможность писать напрямую в поток ответа объекта.

Тогда просто используйте FormDataBodyPart

BodyPart bigPart = new FormDataBodyPart(
        "data", entity, MediaType.APPLICATION_OCTET_STREAM_TYPE);
MultiPart multiPart = new FormDataMultiPart().bodyPart(bigPart);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...