2017-12-13 1 views
4

파일을 보낼 때 ctx.writeAndFlush(new ChunkedFile(new File("file.png")));을 사용할 수 있습니다.청크 작성 방법 <Object> in Netty

어때 약 List<Object>?

목록에 Stringbytes of image이 포함되어 있습니다.

설명서에는 ChunkedInput()이 있지만 사용법을 알 수는 없습니다.

UPDATE

은 내가 수행 한 List<Object>를 보낼 위치의이 channelRead0(ChannelHandlerContext ctx, Object o) 방법 안에, 내 처리기에서 말을하자

@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

그냥 ChunkedInput<ByteBuf> 자신을 구현 다음과 같습니다. 다음과 같이 당신이 그것을 구현할 수의 Netty와 함께 제공된 구현을 다음

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을 참조하십시오. 따라서 다운 스트림에 추가하십시오. 여기에 문서에서 인용은 다음과 같습니다

비동기 적으로 큰 데이터 스트림 를 작성하지 둘 메모리를 많이 소비도 OutOfMemoryError을 얻기에 대한 지원을 추가하는 ChannelHandler. 파일 전송과 같은 대규모 데이터 스트리밍은 ChannelHandler 구현에서 복잡한 상태 관리가 필요합니다. ChunkedWriteHandler은 복잡한 상태를 관리하므로 큰 문제없이 데이터 스트림을 보낼 수 있습니다.

+0

단지 참고 사항 ... 파일을 보내고 파이프 라인에서 내용을 조작 할 필요가 없다면'DefaultFileRegion'을 사용해야합니다. 왜냐하면'sendfile (...) '을 사용할 수 있기 때문입니다. 일컬어 제로 카피 파일 전송. –

+0

@ St.Antario - 내 질문에 답변 해 주셔서 감사합니다! 정말 고맙습니다. 당신의 답이 저에게 해결책을 줄 수 있다고 생각합니다. 정말 ChunkedInput()을 사용하지 않습니다. 제게 좀 더 명확하게 해주시겠습니까? 내 처리기 내에서'channelRead0 (ChannelHandlerContext ctx, Object o) '에 내 질문을 이미 업데이트했습니다. 어떻게 주어진 솔루션을 사용할 수 있습니까? 정말 고맙습니다! – Polar

+0

@Polar는 약간의 정보를 추가했습니다 :) –

관련 문제