我从一个HTTP请求的响应开始:
InputStream responseInputStream = response.getEntityInputStream()我需要对响应进行gzip压缩,这样我就可以将其上传到s3并压缩保存:
this.s3.putObject(new PutObjectRequest(bucketName, key, gzippedResponseInputStream, meta));我知道我可以从responseInputStream中获得byte[]数组,然后将它们压缩到一个新的InputStream中。然而,对于大量的数据,这可能是非常低效的。
我知道在SO上也有类似的问题,但我还没有找到任何东西来解决从InputStream开始,以压缩的InputStream结束的特定需求。
谢谢你的帮助!
发布于 2016-08-13 02:50:50
public final class Example {
public static void main(String[] args) throws IOException, InterruptedException {
final PipedInputStream inputStream = new PipedInputStream();
final PipedOutputStream outputStream = new PipedOutputStream(inputStream);
Thread compressorThread = new Thread() {
@Override
public void run() {
try (FileInputStream dataSource = new FileInputStream(args[0])) {
try (GZIPOutputStream sink = new GZIPOutputStream(outputStream)) {
final byte[] buffer = new byte[8 * 1024];
for (int bytesRead = dataSource.read(buffer); bytesRead >= 0; bytesRead = dataSource.read(buffer)) {
sink.write(buffer, 0, bytesRead);
}
}
} catch (IOException ex) {
//TODO handle exception -> maybe use callable + executor
}
}
};
compressorThread.start();
try (FileOutputStream destination = new FileOutputStream(args[1])) {
final byte[] buffer = new byte[8 * 1024];
for (int bytesRead = inputStream.read(buffer); bytesRead >= 0; bytesRead = inputStream.read(buffer)) {
destination.write(buffer, 0, bytesRead);
}
}
compressorThread.join();
}
}你是对的,我之前的例子是错的。您可以使用管道流。这里的问题是,您不能使用来自同一线程的输入流和输出流。另外,别忘了在写线程时使用join()。您可以通过提供两个参数来测试我的示例:
PS:@11thdimension比他的管道流解决方案快了几分钟,所以如果你觉得这对你有帮助,请接受他的回答
发布于 2016-08-13 03:49:50
我想你要找的是PipedInputStream
以下是如何做到这一点。
public InputStrema getGZipStream() {
final PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream();
try (final InputStream responseInputStream = response.getEntityInputStream();
){
pis.connect(pos);
Thread thread = new Thread() {
public void run () {
startWriting(pos, responseInputStream);
}
};
thread.start();
} catch(Exception e) {
e.printStackTrace();
}
return pis;
}
public void startWriting(OutputStream out, InputStream in) {
try (GZIPOutputStream gOut = GZIPOutputStream(out);) {
byte[] buffer = new byte[10240];
int len = -1;
while ((len = in.read(buffer)) != -1) {
gOut.write(buffer, 0, len);
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
out.close();
} catch( Exception e) {
e.printStackTrace();
}
}
}我还没有测试过这段代码,请让我知道这是否可以工作。
https://stackoverflow.com/questions/38924585
复制相似问题