2017-12-13 34 views
4

ファイルを送信するときには、ctx.writeAndFlush(new ChunkedFile(new File("file.png")));とすることができます。リストをチャンクする方法 in Netty

どのように約List<Object>

リストには、Stringbytes of imageが含まれています。

文書にはChunkedInput()がありますが、私はそれを利用することができません。

UPDATE

のは、私はちょうどChunkedInput<ByteBuf>あなた自身を実装するには、以下の

@Override 
protected void channelRead0(ChannelHandlerContext ctx, Object o) throws Exception { 

    List<Object> msg = new ArrayList<>(); 

    /**getting the bytes of image**/ 
    byte[] imageInByte; 
    BufferedImage originalImage = ImageIO.read(new File(fileName)); 
    // convert BufferedImage to byte array 
    ByteArrayOutputStream bAoS = new ByteArrayOutputStream(); 
    ImageIO.write(originalImage, "png", bAoS); 
    bAoS.flush(); 
    imageInByte = baos.toByteArray(); 
    baos.close(); 

    msg.clear(); 
    msg.add(0, "String"); //add the String into List 
    msg.add(1, imageInByte); //add the bytes of images into list 

    /**Chunk the List<Object> and Send it just like the chunked file**/ 
    ctx.writeAndFlush(new ChunkedInput(DONT_KNOW_WHAT_TO_DO_HERE)); // 

} 

答えて

2

をやったList<Object>を送りたいchannelRead0(ChannelHandlerContext ctx, Object o)メソッドの内部で、私のハンドラにしましょう。次のようにあなたがそれを実装することができネッティーに同梱の実装に続き:

public class ChunkedList implements ChunkedInput<ByteBuf> { 
    private static final byte[] EMPTY = new byte[0]; 
    private byte[] previousPart = EMPTY; 
    private final int chunkSize; 
    private final Iterator<Object> iterator; 

    public ChunkedList(int chunkSize, List<Object> objs) { 
     //chunk size in bytes 
     this.chunkSize = chunkSize; 
     this.iterator = objs.iterator(); 
    } 


    public ByteBuf readChunk(ChannelHandlerContext ctx) { 
     return readChunk(ctx.alloc()); 
    } 

    public ByteBuf readChunk(ByteBufAllocator allocator) { 
     if (isEndOfInput()) 
      return null; 
     else { 
      ByteBuf buf = allocator.buffer(chunkSize); 
      boolean release = true; 
      try { 
       int bytesRead = 0; 
       if (previousPart.length > 0) { 
        if (previousPart.length > chunkSize) { 
         throw new IllegalStateException(); 
        } 
        bytesRead += previousPart.length; 
        buf.writeBytes(previousPart); 
       } 
       boolean done = false; 
       while (!done) { 
        if (!iterator.hasNext()) { 
         done = true; 
         previousPart = EMPTY; 
        } else { 
         Object o = iterator.next(); 
         //depending on the encoding 
         byte[] bytes = o instanceof String ? ((String) o).getBytes() : (byte[]) o; 
         bytesRead += bytes.length; 
         if (bytesRead > chunkSize) { 
          done = true; 
          previousPart = bytes; 
         } else { 
          buf.writeBytes(bytes); 
         } 
        } 
       } 
       release = false; 
      } finally { 
       if (release) 
        buf.release(); 
      } 
      return buf; 
     } 
    } 

    public long length() { 
     return -1; 
    } 

    public boolean isEndOfInput() { 
     return !iterator.hasNext() && previousPart.length == 0; 
    } 

    public long progress() { 
     return 0; 
    } 

    public void close(){ 
     //close 
    } 
} 

ChunkedContentを書き込むためにNettyに同梱の特別なハンドラがあります。 io.netty.handler.stream.ChunkedWriteHandlerを参照してください。だからあなたの下流に追加するだけです。

ChannelHandler非同期的に大規模なデータ・ストリーム を書いていないどちらも多くのメモリを費やしたり OutOfMemoryErrorを取得するためのサポートが追加されています。ここではドキュメントからの引用です。ファイル転送などの大きなデータストリーミングでは、ChannelHandlerの実装では、 複雑な状態管理が必要です。 ChunkedWriteHandlerは、このような複雑な状態を管理するため、大きなデータストリームを問題なく送信することができます。

+0

ちょっと注意してください...ファイルを送信し、パイプラインでそのコンテンツを操作する必要がない場合、あなたは 'sendfile(...)'を使用できるように 'DefaultFileRegion'を実際に使うべきです。別名ゼロコピーファイル転送。 –

+0

@ St.Antario - 私の質問にお答えいただきありがとうございます!私は本当にありがとうと私はあなたの答えは私に解決策を与えることができると思う、私は本当に 'ChunkedInput()'の使用を取得しないので、あなたは私のためにもっと明確にしてくださいできますか?ハンドラの中で、 'channelRead0(ChannelHandlerContext ctx、Object o)'の質問を既に更新しています。あなたのソリューションをどのように使うことができますか?どうもありがとうございます! – Polar

+0

@Polarはいくつかの情報を追加しました:) –

関連する問題