前言
之前项目需要上传大文件的功能,上传大文件经常遇到上传一半由于网络或者其他一些原因上传失败。然后又得重新上传(很麻烦),所以就想能不能做个断点上传的功能。于是网上搜索,发现市面上很少有断点上传的案例,有找到一个案例也是采用套接字作为上传方式(大文件上传,不适合使用,得到形式)。由于大文件夹不适合http上传的方式,所以就想能不能把大文件切割成n块小文件,然后上传这些小文件,所有小文件全部上传成功后再在服务器上进行拼接。这样不就可以实现断点上传,又解决了http不适合上传大文件的难题了吗! ! !
原理分析
<强> Android客户端强>
首先,android端调用服务器接口1,参数为文件名(服务器标识判断是否上传过)
如果存在文件名,说明之前上传过,则续传,如果没有,则从零开始上传。
然后,android端调用服务器接口2,传入参数名,chunck(传到第几块),chuncks(总共多少块)
<>强服务器端强>
接口一:根据上传文件名称文件名判断是否之前上传过,没有则返回客户端chunck=1,有则读取记录chunck并返回。
接口二:上传文件,如果上传块数chunck=chuncks,遍历所有块文件拼接成一个完整文件。
<>强,服务端源代码强>
服务器接口1
@WebServlet (urlpattern={"/ckeckFileServlet "}) 公开课CkeckFileServlet扩展HttpServlet { 私人FileUploadStatusServiceI statusService; 字符串repositoryPath; 字符串uploadPath; @Override 公共空init (ServletConfig配置)抛出ServletException { ServletContext ServletContext=config.getServletContext (); WebApplicationContext上下文=WebApplicationContextUtils.getWebApplicationContext (servletContext); statusService=(FileUploadStatusServiceI) context.getBean (“fileUploadStatusServiceImpl”); repositoryPath=FileUtils.getTempDirectoryPath (); uploadPath=config.getServletContext () .getRealPath(“数据/上传”);=新文件(uploadPath); 如果(! up.exists ()) { up.mkdir (); } } @Override 保护无效doGet (HttpServletRequest点播,HttpServletResponse resp)抛出ServletException IOException {//TODO自动生成方法存根 字符串文件名=新的字符串(req.getParameter("文件名"));//字符串块=req.getParameter(“块”);//System.out.println(块); System.out.println(文件名); resp.setContentType(“文本/json;charset=utf - 8”);=statusService.get TfileUploadStatus文件(文件名); 尝试{ 如果(文件!=null) { int schunk=file.getChunk (); deleteFile (uploadPath + schunk +“_”+文件名);//长了=schunk * Long.parseLong (chunkSize); resp.getWriter ()。写(“{\“\”:“+ schunk + "} "); 其他}{ resp.getWriter () .write (“{\“\”: 1}”); } }捕捉(异常e) {//TODO自动生成的catch块 e.printStackTrace (); } } } >之前服务器接口2
@WebServlet (urlpattern={"/uploaderWithContinuinglyTransferring "}) 公开课UploaderServletWithContinuinglyTransferring扩展HttpServlet { 私有静态最终长serialVersionUID l=1; 私人FileUploadStatusServiceI statusService; 字符串repositoryPath; 字符串uploadPath; @Override 公共空init (ServletConfig配置)抛出ServletException { ServletContext ServletContext=config.getServletContext (); WebApplicationContext上下文=WebApplicationContextUtils.getWebApplicationContext (servletContext); statusService=(FileUploadStatusServiceI) context.getBean (“fileUploadStatusServiceImpl”); repositoryPath=FileUtils.getTempDirectoryPath (); 系统。println(“临时目录:“+ repositoryPath); uploadPath=config.getServletContext () .getRealPath(“数据/上传”); 系统。println(“目录:“+ uploadPath);=新文件(uploadPath); 如果(! up.exists ()) { up.mkdir (); } } @SuppressWarnings(“unchecked”) 公共空间doPost (HttpServletRequest请求,HttpServletResponse响应)抛出ServletException, IOException { response.setCharacterEncoding(“utf - 8”); 整数schunk=零;//分割块数 整数schunks=零;//总分割数 字符串名称=零;//文件名 BufferedOutputStream outputStream=零; 如果(ServletFileUpload.isMultipartContent(请求)){ 尝试{ DiskFileItemFactory工厂=new DiskFileItemFactory (); factory.setSizeThreshold (1024); 工厂。setRepository(新文件(repositoryPath));//设置临时目录 ServletFileUpload上传=new ServletFileUpload(工厂); upload.setHeaderEncoding (“utf - 8”); 上传。setSizeMax(5 * 1024 * 1024 * 1024);//设置附近大小 Listandroid中okhttp实现断点上传示例