当前位置:网站首页>Php+flash large file breakpoint continuation function sharing
Php+flash large file breakpoint continuation function sharing
2022-06-12 19:00:00 【Game programming】
What we usually do is upload files , Upload folder is similar to upload file , But there are some differences , This time I upload the folder and record it for later use .
The needs of this project :
Support the upload and renewal of large files , All browsers are required to be supported for renewal , Include ie6,ie7,ie8,ie9,Chrome,Firefox,360 Secure browser , And can still renew after refreshing the browser , Restart browser ( Close the browser and then open ) Still able to upload , You can still upload after you restart your computer
Support folder upload , It is required that the server can keep the hierarchy , And can continue to pass . Need to support 10 More than ten thousand folders are uploaded .
Support for lower versions of systems and browsers , Because the final running environment of this project is , The configurations are all average , The staff are all for office use , Not much memory , Basically with Windows XP The main system of .
1、 Introduce enctype
enctype Property specifies how the form data should be encoded before it is sent to the server .
enctype The function is to inform the server of the request body MIME type ( Request header content-type It does the same thing )
1、1 enctype There are three values of
| value | describe |
| application/x-www-form-urlencoded | Encode all characters before sending ( Default ) |
| multipart/form-data | No character encoding . Each form item is divided into one part |
| text/plain | Space to “+” plus , But no special character encoding . |
- When enctype=’application/x-www-form-urlencoded’
2. When enctype=’multipart/form-data’
Through observation, it is found that the request body has changed . This request body is called a multi part request body .
What is a multipart request body : It is to divide each form item into one part .
With a request content-type Of boundary The following random string is used as the partition identifier
Common form items :
//name In a text box name The attribute value , and admin Is the text value we entered
Content-Disposition: form-data; name="username"
admin
File form items
//filename It means : The name of the file we uploaded ,content-Type It means :MIME type ,asdasdas It means : Contents of the document
Content-Disposition: form-data; name="upload"; filename="a.txt"
Content-Type: text/plain
asdasdas
- When enctype=’text/plain’


w3c call : The space will become ”+” plus , But I didn't find , Only when get On request , The space will become ”+” Number


Get to the point
Complete upload needs to meet 3 A necessary condition
Provide form Forms ,method Must be post, because get The requested transmission data is generally 2kb, Different browsers are different .
form form properties enctype It has to be multipart/form-data
Provide input type=”file” Class
How it works : When enctype The value of is multipart/form-data when , The browser will split each form item , Split into different parts , With boundary The value of is the partition ID , The string of this token is randomly generated , There will be two more at the end of the split identification string for the last form item ”- -“, For the end . The service side with request.getHeader(“content-type”) Get split string , And then parse .


Code implementation
One 、 Development environment construction
Prepare two third parties jar package
commons-io package
commons-upload package
All dependency packages


Code implementation
<%@ page language="java" import="up6.DBFile" pageEncoding="UTF-8"%>
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ page import="up6.FileBlockWriter" %>
<%@ page import="up6.XDebug" %>
<%@ page import="up6.*" %>
<%@ page import="up6.biz.*" %>
<%@ page import="org.apache.commons.fileupload.FileItem" %>
<%@ page import="org.apache.commons.fileupload.FileItemFactory" %>
<%@ page import="org.apache.commons.fileupload.FileUploadException" %>
<%@ page import="org.apache.commons.fileupload.disk.DiskFileItemFactory" %>
<%@ page import="org.apache.commons.fileupload.servlet.ServletFileUpload" %>
<%@ page import="org.apache.commons.lang.*" %>
<%@ page import="java.net.URLDecoder"%>
<%@ page import="java.util.Iterator"%>
<%@ page import="net.sf.json.JSONObject"%>
<%@ page import="java.util.List"%>
<%
out.clear();
String uid = request.getHeader("uid");//
String id = request.getHeader("id");
String lenSvr = request.getHeader("lenSvr");
String lenLoc = request.getHeader("lenLoc");
String blockOffset = request.getHeader("blockOffset");
String blockSize = request.getHeader("blockSize");
String blockIndex = request.getHeader("blockIndex");
String blockMd5 = request.getHeader("blockMd5");
String complete = request.getHeader("complete");
String pathSvr = "";
// The parameter is empty.
if( StringUtils.isBlank( uid )
|| StringUtils.isBlank( id )
|| StringUtils.isBlank( blockOffset ))
{
XDebug.Output("param is null");return;
}
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List files = null;
try {files = upload.parseRequest(request);}
catch (FileUploadException e)
{out.println("read file data error:" + e.toString());return;}
FileItem rangeFile = null;
Iterator fileItr = files.iterator();
while (fileItr.hasNext())
{
rangeFile = (FileItem) fileItr.next();
if(StringUtils.equals( rangeFile.getFieldName(),"pathSvr"))
{
pathSvr = rangeFile.getString();
pathSvr = PathTool.url_decode(pathSvr);
}
}
boolean verify = false;
String msg = "";
String md5Svr = "";
long blockSizeSvr = rangeFile.getSize();
if(!StringUtils.isBlank(blockMd5)){md5Svr = Md5Tool.fileToMD5(rangeFile.getInputStream());}
verify = Integer.parseInt(blockSize) == blockSizeSvr;
if(!verify){ msg = "block size error sizeSvr:" + blockSizeSvr + "sizeLoc:" + blockSize;}
if(verify && !StringUtils.isBlank(blockMd5))
{
verify = md5Svr.equals(blockMd5); if(!verify) msg = "block md5 error";
}
if(verify)
{
FileBlockWriter res = new FileBlockWriter();
if( Integer.parseInt(blockIndex)==1) res.CreateFile(pathSvr,Long.parseLong(lenLoc));
res.write( Long.parseLong(blockOffset),pathSvr,rangeFile);
up6_biz_event.file_post_block(id,Integer.parseInt(blockIndex));
JSONObject o = new JSONObject();
o.put("msg", "ok");
o.put("md5", md5Svr);
o.put("offset", blockOffset);
msg = o.toString();
}
rangeFile.delete();
out.write(msg);
%>
Download the necessary conditions
Two heads and one stream
content-type
Content-Type It's a very important part of the return message , Indicates what the document content belongs to MIME type .
The browser will follow Content-Type To decide how to display the body content of the returned message .
The default value is text/html
have access to request.getServletContext().getMimeType(“ file name ”) obtain MIME type .
Content-Disposition
Content-disposition yes MIME Protocol extension ,MIME Agreement instructions MIME How the user agent displays the attached files .
The default value is inline, Open in browser window .
When the server sends files to the client browser , If it's a browser supported file type , It will be opened by browser by default , such as txt、jpg etc. , Will be directly in the browser It shows that .
If you need to prompt the user to save , utilize Content-Disposition Do something about it , The key is to add attachment.
for example :Content-Disposition:attachment;filename=xxx, The browser will activate the download box dialog , attachment Means attachment , filname Followed by the name of the file displayed in the download box .
flow
Download is to respond to the client byte data ! Turn a file into an array of bytes , Use response.getOutputStream()
To respond to the browser .
The code is as follows , This code has implemented the breakpoint renewal function , Users can pause during the download process , And continue to download , The pressure on the server is also relatively small .
String fid = request.getHeader("id");
String blockIndex = request.getHeader("blockIndex");// be based on 1
String blockOffset = request.getHeader("blockOffset");// Block offset , Relative to the whole document
String blockSize = request.getHeader("blockSize");// Block size ( The current download size )
String pathSvr = request.getHeader("pathSvr");// The location of the file on the server
pathSvr = PathTool.url_decode(pathSvr);
if ( StringUtils.isBlank(fid)
||StringUtils.isBlank(blockIndex)
||StringUtils.isEmpty(blockOffset)
||StringUtils.isBlank(blockSize)
||StringUtils.isBlank(pathSvr))
{
response.setStatus(500);
response.setHeader("err"," The parameter is empty. ");
return;
}
File f = new File(pathSvr);
// file does not exist
if(!f.exists())
{
response.setStatus(500);
OutputStream os = response.getOutputStream();
System.out.println(String.format("%s file does not exist ",pathSvr));
os.close();
return;
}
long fileLen = f.length();
response.setContentType("application/x-download");
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.addHeader("Content-Length",blockSize);
response.setDateHeader("Expires", 0);
OutputStream os = response.getOutputStream();
try
{
RandomAccessFile raf = new RandomAccessFile(pathSvr,"r");
int readToLen = Integer.parseInt(blockSize);
int readLen = 0;
raf.seek( Long.parseLong(blockOffset) );// Positioning index
byte[] data = new byte[1048576];
while( readToLen > 0 )
{
readLen = raf.read(data,0,Math.min(1048576,readToLen) );
readToLen -= readLen;
os.write(data, 0, readLen);
}
os.flush();
os.close();
raf.close();
os = null;
response.flushBuffer();
out.clear();
out = pageContext.pushBody();
}
catch(Exception e)
{
response.setStatus(500);
os.close();
out.close();
e.printStackTrace();
}
finally
{
if(os != null)
{
os.close();
os = null;
}
out.clear();
out = pageContext.pushBody();
}%>
Load file list , Show it in the download list
The back-end code logic is mostly the same , Can currently support MySQL,Oracle,SQL. Before use, you need to configure the database , You can refer to this article I wrote :java http Large file breakpoint continuous upload – Zeyou software blog
Welcome to join the group to discuss “374992201”
author : Diving Octopus
Game programming ️, A game development favorite ~
If the picture is not displayed for a long time , Please use Chrome Kernel browser .
边栏推荐
- Start with no place to live
- 【矩阵论 & 图论】期末考试复习思维导图
- leetcode:6097. 替换字符后匹配【set记录 + 相同长度逐一查询】
- Research Report on global and Chinese cosmetics industry market sales scale forecast and investment opportunities 2022-2028
- A journey of database full SQL analysis and audit system performance optimization
- Attack and defense world (WEB) -- supersqli
- 六石认知学:大脑的显速与潜速
- On how to make digital transformation after the loan of large policy banks- Yixinhuachen
- OpenGL shadow implementation (soft shadow)
- Operational research optimization of meituan intelligent distribution system - Notes
猜你喜欢

Embedded development: 6 necessary skills for firmware engineers
![leetcode:6095. Strong password verifier II [simple simulation + direct false]](/img/31/570ebaecdd4e6db4dede9a456741a5.png)
leetcode:6095. Strong password verifier II [simple simulation + direct false]

【矩阵论 & 图论】期末考试复习思维导图

The Bean Validation API is on the classpath but no implementation could be found

Redis中的事务

io.seata.common.exception.FrameworkException: can not connect to services-server.

国内如何下载ProxyStrike

美团获得小样本学习榜单FewCLUE第一!Prompt Learning+自训练实战

攻防世界(web篇)---supersqli

Why my order by create_ Time ASC becomes order by ASC
随机推荐
no available service ‘null‘ found, please make sure registry config correct
每日一博 - 微服务权限一二事
Delivery lead time lightweight estimation practice - Notes
Judging the quality of American advanced anti DDoS servers depends on three points!
kali通过iptables实现端口转发功能
Can't understand kotlin source code? Starting with the contracts function~
CVPR 2022 Oral 大连理工提出SCI:快速、超强的低光照图像增强方法
A journey of database full SQL analysis and audit system performance optimization
Dumi builds a document blog
leetcode:6095. 强密码检验器 II【简单模拟 + 不符合直接False】
Meituan won the first place in fewclue in the small sample learning list! Prompt learning+ self training practice
Research Report on global and Chinese cosmetics industry market sales scale forecast and investment opportunities 2022-2028
MySQL数据库(28):变量 variables
吃饭咯 干锅肥肠 + 掌中宝!
Leetcode topic [string] - Sword pointing offer 05- replace spaces
Cookie & session & kaptcha verification code
觀察網站的頁面
Leetcode 494. Objectives and
Leetcode topic [string]-541- reverse string II
OpenGL shadow implementation (hard shadow)