2016-10-26 17 views
1

私の目標は、にあるハング出力ストリームをプッシュすることができます。したがって、ステップ2のoutputstreaminputstreamに変換する必要があります。このため私はPipedInputStreamを使用することに決めました。のwriteTo PipedOutputStreamのは、ちょうど

ただし、コードはwriteTo(out);のステップでハングアップしています。このコードはgrailsアプリケーションにあります。コードがハングしたときにCPUが高く消費されていない。

import org.apache.commons.imaging.formats.jpeg.xmp.JpegXmpRewriter; 

AmazonS3Client client = nfile.getS3Client() //get S3 client 
S3Object object1 = client.getObject(
        new GetObjectRequest("test-bucket", "myfile.jpg")) //get the object. 

InputStream isNew1 = object1.getObjectContent(); //create input stream 
ByteArrayOutputStream os = new ByteArrayOutputStream(); 
PipedInputStream inpipe = new PipedInputStream(); 
final PipedOutputStream out = new PipedOutputStream(inpipe); 

try { 
    String xmpXml = "<x:xmpmeta>" + 
    "\n<Lifeshare>" + 
    "\n\t<Date>"+"some date"+"</Date>" + 
    "\n</Lifeshare>" + 
    "\n</x:xmpmeta>";/ 
    JpegXmpRewriter rewriter = new JpegXmpRewriter(); 
    rewriter.updateXmpXml(isNew1,os, xmpXml); //This is step2 

    try { 
new Thread(new Runnable() { 
    public void run() { 
     try { 
      // write the original OutputStream to the PipedOutputStream 
      println "starting writeto" 
      os.writeTo(out); 
      println "ending writeto" 
     } catch (IOException e) { 
      // logging and exception handling should go here 
     } 
    } 
}).start(); 

     ObjectMetadata metadata = new ObjectMetadata(); 
     metadata.setContentLength(1024); //just testing 
     client.putObject(new PutObjectRequest("test-bucket", "myfile_copy.jpg", inpipe, metadata)); 
     os.writeTo(out); 

     os.close(); 
     out.close(); 
    } catch (IOException e) { 
     // logging and exception handling should go here 
    } 

} 
finally { 
    isNew1.close() 
    os.close() 
    out.close() 
} 

上記のコードは、単にstarting writetoとハングを印刷します。それは別のスレッドでwriteToを置くことによってending writeto

更新 を印刷しません、ファイルは今S3に書き込まれている、しかし、それだけ1024バイトが書かれているされています。ファイルが不完全です。出力ストリームからS3までのすべてをどのように書くことができますか?

+0

PipedOutputStreamに書き込みます:os.writeTo(out)、それに接続されているPipedInputStreamから読み込みますか? – zeppelin

+0

はい、あります。プログラムがそのコードの前にぶら下がっていたので、私はそのコードを表示しませんでしたが、完全性のために今追加しました。 – Omnipresent

答えて

2

os.writeTo(out)を実行すると、ストリーム全体をからにフラッシュしようとしますが、もう一方の側(つまりinpipe)からの読み込みはまだないので、内部バッファがいっぱいになりますスレッドが停止します。

データを書き込む前に読者を設定し、別のスレッドで実行されていることを確認する必要があります(PapedOutputStreamのjavadocを参照)。

+0

私は( 'S3object')のコードを' writeTo'の上に移動しましたが、結果は同じです... – Omnipresent

+0

AmazonS3Clientの代わりにTransferManagerを使用して、アップロードを別のスレッドで行うようにしてください。 – zeppelin

+0

基本的には、client.putObject()はinpipeからの読み込みをブロックします(データが書き込まれていないため)。 – zeppelin