当前位置:网站首页>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 .
边栏推荐
- 从应无所住说起
- Can't understand kotlin source code? Starting with the contracts function~
- dumi 搭建文档型博客
- lua记录
- 美团智能配送系统的运筹优化实战-笔记
- Kali implements port forwarding through iptables
- Mysql database experiment I data definition
- Research Report on current market situation and investment prospect of China's tobacco RFID industry 2022-2027
- The practice of machine learning in meituan distribution system: restoring the real world with technology - Notes
- Daily blog - micro service permission 12 matters
猜你喜欢

Redis中的事务

OpenGL shadow implementation (hard shadow)

YOLOX网络结构详解
![[0008] unordered list](/img/16/7525d963e68757558dd55ff4d1a23a.png)
[0008] unordered list
![leetcode:5289. Distribute cookies fairly [see data range + DFS pruning]](/img/be/820bfb3aaf23a397e65f96693770f2.png)
leetcode:5289. Distribute cookies fairly [see data range + DFS pruning]
![leetcode:6095. Strong password verifier II [simple simulation + direct false]](/img/31/570ebaecdd4e6db4dede9a456741a5.png)
leetcode:6095. Strong password verifier II [simple simulation + direct false]

超级重磅!Apache Hudi多模索引对查询优化高达30倍

kali局域网ARP欺骗(arpspoof)并监听(mitmproxy)局域内其它主机上网记录

Exploration of a flexible injection scheme for istio sidecar

Kali LAN ARP Spoofing and monitoring other hosts' Internet access records in the LAN
随机推荐
no available service ‘null‘ found, please make sure registry config correct
no available service ‘null‘ found, please make sure registry config correct
leetcode:5270. 网格中的最小路径代价【简单层次dp】
【图像去噪】基于各向异性滤波实现图像去噪附matlab代码
[5gc] Introduction to three SSC (session and service continuity) modes
美团智能配送系统的运筹优化实战-笔记
数据库全量SQL分析与审计系统性能优化之旅
Leetcode 416. Split equal sum subset
什么是网络代理
Common troubleshooting tools and analysis artifacts are worth collecting
[blockbuster release] ant dynamic card, enabling the app home page to realize agile update
Report on market demand trends and future strategic planning recommendations of the global and Chinese smart financial solutions industry 2022-2028
笔记本电脑清灰打硅脂后,开机一直黑屏,如何破?
Cookie & session & kaptcha verification code
Redis中的事务
bilibili视频列表名字太长显示不全的解决方法
Operational research optimization of meituan intelligent distribution system - Notes
【矩阵论 & 图论】期末考试复习思维导图
A journey of database full SQL analysis and audit system performance optimization
The difference between user status and system status in CRM