我試圖從java服務器應用程序發送文件(pdf/bpm/jpg/png)到java客戶端應用程序。 該文件以塊形式發送。但是,如何知道文件何時完全發送?Netty:如何確定文件是否已完整發送?
我的第一個想法是使用得到通知,如果文件已完全發送。但是由於它在文件仍在發送時也被觸發,所以它是無用的。有關如何進行的任何建議?
客戶端管道:
ChannelPipeline p = ch.pipeline();
p.addLast("FileChunkHandler", new FileChunkHandler());
服務器管道:
p.addLast("Encoder", new ObjectEncoder());
p.addLast("Decoder", new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(null)));
p.addLast("chunkedWriteHandler", new ChunkedWriteHandler());
p.addLast("FileSenderHandler", new FileSenderHandler());
的FileChunkHandler在客戶端:
public class FileChunkHandler extends SimpleChannelInboundHandler<ChunkedFile>{
private ObjectOutputStream oout = null;
@Override protected void channelRead0(ChannelHandlerContext ctx, ChunkedFile msg) throws Exception{
System.out.println("channelRead0");
if (oout == null){
FileOutputStream out = new FileOutputStream("/Users/user/Documents/tmp/test/bla.txt");
oout = new ObjectOutputStream(out);
}
ByteBuf buf = (ByteBuf)msg;
int numberOfReadableBytes = buf.readableBytes();
byte[] bytes = new byte[numberOfReadableBytes];
buf.readBytes(bytes);
oout.write(bytes, 0, bytes.length);
}
@Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception{
System.out.println("channelReadComplete");
ctx.fireChannelReadComplete();
}
}
的FileSenderHandler在服務器上:
公共類FileSenderHandler擴展ChannelInboundHandlerAdapter {
@Override public void channelRegistered(ChannelHandlerContext ctx) throws Exception{
File file = new File("/Users/user/Documents/tmp/test/test.txt");
RandomAccessFile raf = new RandomAccessFile(file, "r");
ChannelFuture sendFileFuture = null;
if (ctx.pipeline().get(SslHandler.class) == null) {
sendFileFuture = ctx.write(new DefaultFileRegion(raf.getChannel(), 0, raf.length()), ctx.newProgressivePromise());
ctx.flush();
} else {
sendFileFuture = ctx.writeAndFlush(file, ctx.newProgressivePromise());
}
sendFileFuture.addListener(new ChannelProgressiveFutureListener() {
@Override
public void operationProgressed(ChannelProgressiveFuture future, long progress, long total) {
if (total < 0) { // total unknown
System.err.println(future.channel() + " Transfer progress: " + progress);
} else {
System.err.println(future.channel() + " Transfer progress: " + progress + "/" + total);
}
}
@Override
public void operationComplete(ChannelProgressiveFuture future) {
System.err.println(future.channel() + " Transfer complete.");
}
});
ctx.fireChannelRegistered();
}
由於這種方法需要大量重構我們的代碼,所以這不是一個選項... – KayJ