最近写一个大文件数据通过分包方式上传Web服务器小需求,文件数据按照文件分包后的先后顺序进行上报。大致流程:
1,文件准备上报请求
1)客户端计算即将上传的文件的大小、crc校验码;
2)发送文件信息到服务器,包括文件大小、校验码CRC,文件格式;
3)Web服务端在接收到文件上传请求后,生成中心唯一fileId,同时以该fileId作为缓存主键,缓存文件信息。并在指定路径生成以fileId命名的临时文件。
String fileId=UUID.randomUUID().toString()。String parentPath = request.getServletContext().getRealPath("/")+"tempFile/";File file = newFile(parentPath,fileName);
file.createNewFile();4)Web服务器将该fileid做为请求响应,反馈给客户端。
2,文件数据上报请求
1),客户端将要上报文件按照一定大小进行分包。
2),客户端通过HTTP上传分包数据,消息头包括fileid,分包数据在整个文件的偏移量(offset)、分包数据的长度(dataLen),
分包数据的校验码(crc)以及分包数据消息体。
3),Web服务端在收到数据请求时,先判断该fileid缓存是否存在,如果存在该fileid缓存,读取请求的消息体数据,
先进行数据校验。校验成功,根据解析的fileid,打开在指定路径的临时文件,将消息体数据追加写入临时文件:
String filePath = request.getServletContext().getRealPath("/tempFile/");File file = newFile(filePath,fileName);FileOutputStream fileOutputStream = newFileOutputStream(file, true);
4),客户端和Web服务器重复第2、3步。判断已接收的分包数据总大小是否和文件大小一致。如果一致,表面文件已经接收完整,
计算接收完毕的文件crc校验码,和在请求阶段上传的总文件的CRC校验码进行比对。一致则该文件成功接收,否则删除该临时文件,
并通知客户端文件接收失败。InputStream inputStream = request.getInputStream();
bytebuffer[] = new byte[content_length];
intoff_set=1;
inttotalRead=0;
while(off_set>0){
off_set = inputStream.read(buffer,totalRead,buffer.length-totalRead);
if(off_set>-1)
totalRead=totalRead+off_set;
}
inputStream.close();
crc校验部分:publicString getCheckCrc(FileInputStream fileInputStream){
byte[] buffer = new byte[Length];
String result="";
CRC32 crc32 = newCRC32();
try{
if(fileInputStream != null) {
intread = 0;
while((read = fileInputStream.read(buffer)) > 0) {
crc32.update(buffer,0,read);
}
fileInputStream.close();
result = String.valueOf(crc32.getValue());
}
}catch(Exception e){
logger.error("getCheckCrc:"+e.toString());
}
returnresult;
}publicString getCheckCrcEx(byte[] temp){
String result="";
try{
byte[] buffer;
intcount=temp.length/Length+1;
CRC32 crc32 = newCRC32();
intlen=0;
for(inti=0;i
if(temp.length
len=temp.length;
}else{
if(i
len=Length;
}else{
len=temp.length-i*Length;
}
}
buffer=new byte[len];
System.arraycopy(temp,i*Length,buffer,0,len);
crc32.update(buffer,0,len);
}
result = String.valueOf(crc32.getValue());
}catch(Exception e){
logger.error("getCheckCrcEx:"+e.toString());
}
returnresult;
}