我正在尝试将多部分请求发送到服务器。这样做时,我正在使用PipedOutputStream和PipedInputStream分别生成和使用数据。接着在MultipartEntityBuilder类中将PipedInputStream用作二进制正文内容。
请求进入阻塞状态-projectModelFuture.isDone()始终为false。
public class MyStreamItemOutputStream
implements StreamItemOutputStream {
private PipedOutputStream pipedOut = new PipedOutputStream();
private PipedInputStream pipedIn;
private Future<ProjectModel> projectModelFuture;
private ExecutorService es = Executors.newSingleThreadExecutor();
MyStreamItemOutputStream(MyClient myClient, ProjectModel projectModel) {
try {
pipedIn = new PipedInputStream(pipedOut, 8*1024);
projectModelFuture = es.submit(() -> myClient.createProject(pipedIn, projectModel));
} catch (Exception e) {
System.out.println("stream.failed="+e.getMessage());
throw e;
}
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
pipedOut.write(b, off, len);
}
@Override
public void close() throws IOException {
try {
while (!projectModelFuture.isDone()) {
System.out.println("===IN-PROGRESS===");
Thread.sleep(5000);
}
ProjectModel createdProject = projectModelFuture.get();
} catch (Exception e) {
System.out.println("stream.failed="+e.getMessage());
throw e;
} finally {
pipedOut.close();
pipedIn.close();
es.shutdown();
}
}
}
public class MyClient
implements Closeable {
private CloseableHttpClient client;
Map<String, String> options;
public DataRobotClient(Map<String, String> options) {
this.options = options;
client = // create httpclient..
}
public ProjectModel createProject(InputStream in, ProjectModel projectModel) {
ResponseHandler<ProjectModel> responseHandler = response -> {
final StatusLine statusLine = response.getStatusLine();
final String entity = EntityUtils.toString(response.getEntity());
if (StatusLineUtils.isSuccess(statusLine)) {
System.out.println("Success!! " + entity);
} else {
System.out.println("Failed!! " + statusLine);
}
};
try {
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
if (!Strings.isNullOrEmpty(projectModel.getProjectName())) {
entityBuilder.addTextBody("projectName", projectModel.getProjectName());
}
entityBuilder.addBinaryBody("file", in, ContentType.create("text/csv"), projectModel.getFileName());
// MultipartRequestBuilder is a custom class
return client.execute(
MultipartRequestBuilder.post("/projects/")
.setEntity(entityBuilder.build())
.setHeader(HttpHeaders.AUTHORIZATION, "Token xxxsomeTokenGoesHerexxx")
.build(),
responseHandler);
} catch (Exception ce) {
throw ce;
}
}
}
我的期望是PipedOutputStream将数据写入管道,而PipedInputStream将读取数据块,从而消除了内存不足的可能性。
注意:我已经使用ByteArrayOutputStream成功实现了相同的功能,但是它获得的OOM具有大数据。