netty上传文件例子

97 篇文章 1 订阅
/*由于netty本身的性能需求,每次传输的字节数最大为1024个字节,所以如果文件内容小于1024个字节,
只需一次请求就可以上传文件成功;如果文件内容大于1024个字节,需多次分片上传,用到httpchunk,分片处理机制(netty本身自带)。
一次处理不玩,分多次上传。
01*/public class UploadHandler {
02    private static final long serialVersionUID = 1092232169163288262L;
03    protected static String fileUploadPath = "";
04    protected static String fileUploadUrl =  "";
05    protected static String imageUploadPath = "";
06    protected static String imageUploadUrl = "";
07 
08    private boolean          readingChunks = false;
09    private FileOutputStream fOutputStream = null;
10    private boolean          isReadSuccess = true;   
11     
12    public boolean upload(ChannelHandlerContext ctx, MessageEvent e) throws IOException{
13        boolean isUploadFinished=false;
14        Channel channel = e.getChannel();
15            if (e.getMessage().getClass() == DefaultHttpRequest.class){ //第一次请求上传,无论文件大小,都走该请求
16                DefaultHttpRequest request = (DefaultHttpRequest) e.getMessage(); 
17                if( request.isChunked() ){//netty自己分析文件大小,是否需要分片上传文件。
18                    readingChunks = true;
19                }else{
20                    ChannelBuffer buffer = request.getContent();
21                    readFileContent(buffer);
22                    isUploadFinished=true;
23                }
24            } else //netty分片上传的实现
25                HttpChunk httpChunk = (HttpChunk) e.getMessage(); 
26                if (!httpChunk.isLast()){ 
27                    ChannelBuffer buffer = httpChunk.getContent(); 
28                    readFileContent(buffer);
29                } else
30                    readingChunks = false
31                    isUploadFinished=true;
32                
33            
34        return isUploadFinished;
35    }
36     
37    private boolean readFileContent( ChannelBuffer buffer ){
38        try{
39            if (fOutputStream == null){ 
40                ByteArrayOutputStream buf = new ByteArrayOutputStream();
41                while( buffer.readable() ){
42                    byte b = buffer.readByte();
43                    buf.write(b);
44                    if( b == '\n' && new String(buf.toByteArray()).endsWith("\r\n\r\n") ) break;
45                }
46                String content = buf.toString("utf8");
47                FileItem fileItem = FileItem.parseFileItem(content);
48                String name = fileItem.getFieldName();
49                if (!name.equals("file")) return false;
50                String fileName = fileItem.getFilename();
51                if (fileName.indexOf("\\") > -1) {
52                    fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
53                }
54                File file = new File("D://"+fileName);
55                fOutputStream = new FileOutputStream(file);
56            
57            while (buffer.readable()){ 
58                byte[] dst = new byte[buffer.readableBytes()]; 
59                buffer.readBytes(dst); 
60                fOutputStream.write(dst);
61            }
62            fOutputStream.flush();
63            return true;
64        }catch(Exception e){
65            isReadSuccess=false;
66            return false;
67        }
68    }   
69 
70}


//用于封装请求的头信息,获取文件名,文件类型等信息。
01class FileItem{
02    private String filename;
03    private String mimeType;
04    private String fieldName;
05     
06    public FileItem( String filename , String mimeType , String fieldName ) {
07        this.filename = filename;
08        this.mimeType = mimeType;
09        this.fieldName      = fieldName;
10    }
11     
12    public static FileItem parseFileItem( String content ){
13        if( content == null ) return null;
14        String filename = null;
15        String mimeType = null;
16        String name        = null;
17        String[] rows = content.split("\r\n");
18        for( String row : rows ){
19            int idx = row.indexOf(":");
20            if( idx > 0 ){
21                String key = row.substring(0,idx);
22                if("Content-Disposition".equals(key)){
23                    String val = row.substring(idx+1);
24                    String[] items = val.split(";");
25                    for( String item : items ){
26                        String[] kv = item.split("=");
27                        String k = kv[0].trim();
28                        if( "name".equals(k) ){
29                            name = kv[1].replace("\"", "");
30                        }else if( "filename".equals(k) ){
31                            filename = kv[1].replace("\"", "");
32                        }
33                    }
34                }else if( "Content-Type".equals(key) ){
35                    String val = row.substring(idx+1);
36                    mimeType = val.trim();
37                }
38            }
39        }
40        return new FileItem(filename, mimeType, name);
41    }
42     
43    public String getFilename() {
44        return filename;
45    }
46 
47    public String getMimeType() {
48        return mimeType;
49    }
50 
51    public String getFieldName() {
52        return fieldName;
53    }
54     
55    @Override
56    public String toString() {
57        return String.format("name=%s  mimetype=%s  filename=%s", this.fieldName,this.mimeType,this.filename);
58    }
59}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值