【问题标题】:How do I wait to see if my InputStream has received all data to process further?如何等待查看我的 InputStream 是否已收到所有数据以进一步处理?
【发布时间】:2012-08-30 15:38:38
【问题描述】:

我必须将数据写入Amazon S3,然后使用OutputStream 将数据写入其InputStream,如下所示

    final PipedOutputStream outputStream = new PipedOutputStream();
    final PipedInputStream inputStream;
    try {
        inputStream = new PipedInputStream(outputStream);
        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        PutObjectRequest putObjectRequest = new PutObjectRequest(S3EnvironmentConfigurator.BucketTypes.source.name(), getProposalName(uniqueId), inputStream, null);
                        amazonS3Client.putObject(putObjectRequest);
                        try {
                            inputStream.close();
                        } catch (IOException e) {

                        }
                    }
                }
        ).start();

现在amazonS3Client.putObject 看起来像

  @Override
    public PutObjectResult putObject(@Nonnull final PutObjectRequest putObjectRequest)
            throws AmazonClientException, AmazonServiceException {

        try {
            InputStreamReader is = new InputStreamReader(new GZIPInputStream(putObjectRequest.getInputStream()));
            StringBuilder sb=new StringBuilder();
            BufferedReader br = new BufferedReader(is);
            String read = br.readLine();
            while(read != null) {
                System.out.println(read);
                read =br.readLine();

            }
        } catch (IOException e) {
            //ignore
        }
    return super.putObject(putObjectRequest);
  • 这当前会在控制台上打印出内容

需要

我该怎么做类似的事情

while (putObjectRequest.getInputStream() is not completely available) {
   // wait
}

// write inputStream, the entire InputStream is ready and available for processing

【问题讨论】:

  • 为什么需要等待?为什么不等待就不能开始处理?如果数据还没有准备好,当前线程会暂停,直到输入流有新数据。
  • 为什么是管道?在这种情况下没有任何优势。只需在当前线程中执行所有 I/O。

标签: java amazon-s3 inputstream outputstream


【解决方案1】:

一旦侧写关闭其OutputStreamInputStream 将传递任何尚未读取的字节,然后下一个read() 将返回 -1 以指示输入结束。

值字节以int 形式返回,范围为0 到255。如果由于到达流的末尾而没有可用的字节,则返回值-1。此方法会一直阻塞,直到输入数据可用、检测到流结束或引发异常。

如果边写在完成时失败到close(),那么阅读器将阻塞等待更多输入,直到写入过程关闭。

【讨论】:

  • 这是否意味着一旦调用outputSteam.close() ,inputStream 就会保存所有数据?
  • @daydreamer,除非流库有可怕的错误,否则作者可以安全地调用close,读者仍然可以处理所有写入的字节。
  • @daydreamer,当你缓冲时,错误往往会蔓延到一个地方。如果将OutputStream 包装在缓冲输出流中,则需要关闭/刷新缓冲输出流,而不仅仅是它包装的流。
【解决方案2】:

您可以将所有数据复制到字节缓冲区,从而确保您已从输入流中读取所有数据。然后根据这个缓冲区创建新的输入流。比如:

byte[] array = IOUtils.toByteArray(inputStream);
InputStream newInputStream = new ByteArrayInputStream(array);

IOUtils 来自 apache commons。

【讨论】:

    猜你喜欢
    • 2018-01-26
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 2013-01-14
    • 2019-03-15
    相关资源
    最近更新 更多