netty上傳文件例子
/*由于netty本身的性能需求,每次傳輸的字節數最大為1024個字節,所以如果文件內容小于1024個字節,
只需一次請求就可以上傳文件成功;如果文件內容大于1024個字節,需多次分片上傳,用到httpchunk,分片處理機制(netty本身自帶)。
一次處理不玩,分多次上傳。
*/public class UploadHandler {
private static final long serialVersionUID = 1092232169163288262L;
protected static String fileUploadPath = "";
protected static String fileUploadUrl = "";
protected static String imageUploadPath = "";
protected static String imageUploadUrl = "";
private boolean readingChunks = false;
private FileOutputStream fOutputStream = null;
private boolean isReadSuccess = true;
public boolean upload(ChannelHandlerContext ctx, MessageEvent e) throws IOException{
boolean isUploadFinished=false;
Channel channel = e.getChannel();
if (e.getMessage().getClass() == DefaultHttpRequest.class){ //第一次請求上傳,無論文件大小,都走該請求
DefaultHttpRequest request = (DefaultHttpRequest) e.getMessage();
if( request.isChunked() ){//netty自己分析文件大小,是否需要分片上傳文件。
readingChunks = true;
}else{
ChannelBuffer buffer = request.getContent();
readFileContent(buffer);
isUploadFinished=true;
}
} else { //netty分片上傳的實現
HttpChunk httpChunk = (HttpChunk) e.getMessage();
if (!httpChunk.isLast()){
ChannelBuffer buffer = httpChunk.getContent();
readFileContent(buffer);
} else {
readingChunks = false;
isUploadFinished=true;
}
}
return isUploadFinished;
}
private boolean readFileContent( ChannelBuffer buffer ){
try{
if (fOutputStream == null){
ByteArrayOutputStream buf = new ByteArrayOutputStream();
while( buffer.readable() ){
byte b = buffer.readByte();
buf.write(b);
if( b == '\n' && new String(buf.toByteArray()).endsWith("\r\n\r\n") ) break;
}
String content = buf.toString("utf8");
FileItem fileItem = FileItem.parseFileItem(content);
String name = fileItem.getFieldName();
if (!name.equals("file")) return false;
String fileName = fileItem.getFilename();
if (fileName.indexOf("\\") > -1) {
fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
}
File file = new File("D://"+fileName);
fOutputStream = new FileOutputStream(file);
}
while (buffer.readable()){
byte[] dst = new byte[buffer.readableBytes()];
buffer.readBytes(dst);
fOutputStream.write(dst);
}
fOutputStream.flush();
return true;
}catch(Exception e){
isReadSuccess=false;
return false;
}
}
} //用于封裝請求的頭信息,獲取文件名,文件類型等信息。
class FileItem{
private String filename;
private String mimeType;
private String fieldName;
public FileItem( String filename , String mimeType , String fieldName ) {
this.filename = filename;
this.mimeType = mimeType;
this.fieldName = fieldName;
}
public static FileItem parseFileItem( String content ){
if( content == null ) return null;
String filename = null;
String mimeType = null;
String name = null;
String[] rows = content.split("\r\n");
for( String row : rows ){
int idx = row.indexOf(":");
if( idx > 0 ){
String key = row.substring(0,idx);
if("Content-Disposition".equals(key)){
String val = row.substring(idx+1);
String[] items = val.split(";");
for( String item : items ){
String[] kv = item.split("=");
String k = kv[0].trim();
if( "name".equals(k) ){
name = kv[1].replace("\"", "");
}else if( "filename".equals(k) ){
filename = kv[1].replace("\"", "");
}
}
}else if( "Content-Type".equals(key) ){
String val = row.substring(idx+1);
mimeType = val.trim();
}
}
}
return new FileItem(filename, mimeType, name);
}
public String getFilename() {
return filename;
}
public String getMimeType() {
return mimeType;
}
public String getFieldName() {
return fieldName;
}
@Override
public String toString() {
return String.format("name=%s mimetype=%s filename=%s", this.fieldName,this.mimeType,this.filename);
}
} 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!