当输入流开始读取时,输出流开始写入
Outputstream start writing when inputstream starts reading
我想通过 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()));
}
您可以使用 StreamingOutput
并使用您的 CustomSerializer
写入提供的 OutputStream
StreamingOutput entity = new StreamingOutput() {
@Override
public void write(OutputStream out)
throws IOException, WebApplicationException {
CustomSerializer.serialize(bigObject, out);
}
};
Jersey 将调用 write()
方法,让您有机会直接写入响应实体流。
那就用一个FormDataBodyPart
BodyPart bigPart = new FormDataBodyPart(
"data", entity, MediaType.APPLICATION_OCTET_STREAM_TYPE);
MultiPart multiPart = new FormDataMultiPart().bodyPart(bigPart);
我想通过 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()));
}
您可以使用 StreamingOutput
并使用您的 CustomSerializer
写入提供的 OutputStream
StreamingOutput entity = new StreamingOutput() {
@Override
public void write(OutputStream out)
throws IOException, WebApplicationException {
CustomSerializer.serialize(bigObject, out);
}
};
Jersey 将调用 write()
方法,让您有机会直接写入响应实体流。
那就用一个FormDataBodyPart
BodyPart bigPart = new FormDataBodyPart(
"data", entity, MediaType.APPLICATION_OCTET_STREAM_TYPE);
MultiPart multiPart = new FormDataMultiPart().bodyPart(bigPart);