Netty项目中应用:文件下载
private void writeFile(ChannelHandlerContext ctx, String path, boolean delAfterDoing) throws Exception{
File file = new File(path);
RandomAccessFile raf = new RandomAccessFile(file, "r");
long fileLength = raf.length();
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
HttpHeaders.setContentLength(response, fileLength);
TestDispacheHandler.setContentTypeHeader(response, file);
response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
response.headers().set("Content-Disposition", "attachment; filename="+file.getName());
ctx.write(response);
ChannelFuture lastContentFuture = null;
ChannelFuture sendFileFuture = ctx.writeAndFlush(new HttpChunkedInput(new ChunkedFile(raf, 0, fileLength, 8192)),ctx.newProgressivePromise());
lastContentFuture = sendFileFuture;
sendFileFuture.addListener(new FileChannelProgressiveListenerImpl(raf));
if(delAfterDoing){
lastContentFuture.addListener(new FileChannelFutureListenerImpl(ctx, file));
}
else{
lastContentFuture.addListener(ChannelFutureListener.CLOSE);
}
}
public static void setContentTypeHeader(HttpResponse response, File file) {
MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();
response.headers().set(CONTENT_TYPE, mimeTypesMap.getContentType(file.getPath()));
}
/**
* 文件写入进度
* @author SYSTEM
*
*/
class FileChannelProgressiveListenerImpl implements ChannelProgressiveFutureListener{
private RandomAccessFile raf;
public FileChannelProgressiveListenerImpl(RandomAccessFile raf){
this.raf = raf;
}
public void operationProgressed(ChannelProgressiveFuture future, long progress, long total) {
if (total < 0) {
//不知道总长度
System.err.println(future.channel() + " Transfer progress: " + progress);
} else {
System.err.println(future.channel() + " Transfer progress: " + progress + " / " + total);
}
}
public void operationComplete(ChannelProgressiveFuture future) {
System.err.println(future.channel() + " Transfer complete.");
try{
this.raf.close();
}catch(Exception e){
}
}
}
/**
* 文件写完后删除
* @author SYSTEM
*
*/
class FileChannelFutureListenerImpl implements ChannelFutureListener{
private ChannelHandlerContext ctx;
private File file;
public FileChannelFutureListenerImpl(ChannelHandlerContext ctx, File file){
this.ctx = ctx;
this.file = file;
}
@Override
public void operationComplete(ChannelFuture future) throws Exception {
ctx.close();
try{
file.delete();
}catch(Exception e){}
}
}