| package com.example.demo.base.file; |
| |
| import java.io.*; |
| import java.net.URLDecoder; |
| import java.net.URLEncoder; |
| import java.time.LocalDateTime; |
| import java.time.format.DateTimeFormatter; |
| import java.util.List; |
| import java.util.concurrent.ExecutorService; |
| import java.util.concurrent.Executors; |
| |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| |
| import org.apache.commons.io.FileUtils; |
| import org.apache.commons.io.FilenameUtils; |
| import org.apache.http.HttpEntity; |
| import org.apache.http.HttpResponse; |
| import org.apache.http.client.HttpClient; |
| import org.apache.http.client.methods.HttpGet; |
| import org.apache.http.impl.client.HttpClients; |
| import org.apache.tomcat.util.http.fileupload.FileItem; |
| import org.apache.tomcat.util.http.fileupload.RequestContext; |
| import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory; |
| import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload; |
| import org.springframework.stereotype.Controller; |
| import org.springframework.util.ResourceUtils; |
| import org.springframework.web.bind.annotation.PostMapping; |
| import org.springframework.web.bind.annotation.RequestMapping; |
| import org.springframework.web.bind.annotation.ResponseBody; |
| import org.springframework.web.bind.annotation.RestController; |
| import org.springframework.web.multipart.MultipartFile; |
| |
| |
| |
| |
| |
| @RestController |
| @RequestMapping("fileUpload") |
| public class FileController { |
| |
| @PostMapping("upload") |
| public String upload(MultipartFile file) throws IOException { |
| |
| |
| String originalFilename = file.getOriginalFilename(); |
| |
| |
| String extension = ".".concat(FilenameUtils.getExtension(originalFilename)); |
| |
| |
| String newFile = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")).concat(extension); |
| |
| |
| long size = file.getSize(); |
| |
| |
| String contentType = file.getContentType(); |
| |
| |
| String realPath = ResourceUtils.getURL("classpath:").getPath() + "/static/files"; |
| |
| |
| String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); |
| String dataDirPath = realPath.concat("/").concat(format); |
| |
| File fileDir = new File(dataDirPath); |
| |
| if (!fileDir.exists()) { |
| fileDir.mkdirs(); |
| } |
| file.transferTo(new File(fileDir, newFile)); |
| |
| |
| return "Ok"; |
| |
| } |
| |
| private final static String utf8 = "utf-8"; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| @PostMapping("chunkUpload") |
| public void chunkUpload(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) |
| throws Exception { |
| |
| |
| httpServletResponse.setCharacterEncoding(utf8); |
| |
| Integer chunk = null; |
| |
| Integer chunks = null; |
| String name = null; |
| |
| |
| String uploadPath = "C:\\Users\\ChenQ\\Pictures\\TestFile"; |
| BufferedOutputStream os = null; |
| |
| try { |
| DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(); |
| |
| diskFileItemFactory.setSizeThreshold(1048576); |
| |
| diskFileItemFactory.setRepository(new File(uploadPath)); |
| |
| ServletFileUpload upload = new ServletFileUpload(diskFileItemFactory); |
| |
| upload.setFileSizeMax(5L * 1024L * 1024L * 1024L); |
| |
| upload.setSizeMax(10L * 1024L * 1024L * 1024L); |
| |
| List<FileItem> fileItems = upload.parseRequest((RequestContext)httpServletRequest); |
| |
| |
| for (FileItem item : fileItems) { |
| if (!item.isFormField()) { |
| if ("chunk".equals(item.getFieldName())) { |
| chunk = Integer.parseInt(item.getString(utf8)); |
| } |
| if ("chunks".equals(item.getFieldName())) { |
| chunks = Integer.parseInt(item.getString(utf8)); |
| } |
| if ("name".equals(item.getFieldName())) { |
| name = item.getString(utf8); |
| } |
| } |
| } |
| |
| for (FileItem item : fileItems) { |
| |
| if (!item.isFormField()) { |
| String temFileName = name; |
| if (name != null) { |
| if (chunk != null) { |
| temFileName = chunk + "_" + name; |
| } |
| |
| |
| File temFile = new File(uploadPath, temFileName); |
| if (!temFile.exists()) { |
| |
| item.write(temFile); |
| } |
| } |
| } |
| } |
| |
| |
| if (chunk != null && chunk == chunks - 1) { |
| File tempFile = new File(uploadPath, name); |
| os = new BufferedOutputStream(new FileOutputStream(tempFile)); |
| |
| for (int i = 0; i < chunks; i++) { |
| File file = new File(uploadPath, i + "_" + name); |
| while (!file.exists()) { |
| Thread.sleep(100); |
| } |
| byte[] bytes = FileUtils.readFileToByteArray(file); |
| os.write(bytes); |
| os.flush(); |
| file.delete(); |
| } |
| os.flush(); |
| } |
| httpServletResponse.getWriter().write("上传成功" + name); |
| } finally { |
| try { |
| |
| if (os != null) { |
| os.close(); |
| } |
| } catch (Exception exception) { |
| exception.printStackTrace(); |
| } |
| |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| @RequestMapping("/down") |
| public void down(HttpServletRequest request, HttpServletResponse response) throws IOException { |
| response.setCharacterEncoding(utf8); |
| |
| File file = new File("D:\\File\\a.mp4"); |
| InputStream is = null; |
| OutputStream os = null; |
| try { |
| |
| long fSize = file.length(); |
| response.setContentType("application/x-download"); |
| String fileName = URLEncoder.encode(file.getName(), utf8); |
| response.addHeader("Content-Disposition", "attachment;filename=" + fileName); |
| |
| response.setHeader("Accept-Range", "bytes"); |
| |
| response.setHeader("fSize", String.valueOf(fSize)); |
| response.setHeader("fName", fileName); |
| |
| long pos = 0, last = fSize - 1, sum = 0; |
| |
| if (null != request.getHeader("Range")) { |
| response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); |
| String numRange = request.getHeader("Range").replaceAll("bytes=", ""); |
| String[] strRange = numRange.split("-"); |
| if (strRange.length == 2) { |
| pos = Long.parseLong(strRange[0].trim()); |
| last = Long.parseLong(strRange[1].trim()); |
| |
| if (last > fSize - 1) { |
| last = fSize - 1; |
| } |
| } else { |
| |
| pos = Long.parseLong(numRange.replaceAll("-", "").trim()); |
| } |
| } |
| long rangeLenght = last - pos + 1; |
| String contentRange = |
| new StringBuffer("bytes").append(pos).append("-").append(last).append("/").append(fSize).toString(); |
| response.setHeader("Content-Range", contentRange); |
| response.setHeader("Content-Lenght", String.valueOf(rangeLenght)); |
| os = new BufferedOutputStream(response.getOutputStream()); |
| is = new BufferedInputStream(new FileInputStream(file)); |
| is.skip(pos); |
| byte[] buffer = new byte[1024]; |
| int lenght = 0; |
| |
| while (sum < rangeLenght) { |
| lenght = |
| is.read(buffer, 0, (rangeLenght - sum) <= buffer.length ? (int)(rangeLenght - sum) : buffer.length); |
| sum = sum + lenght; |
| os.write(buffer, 0, lenght); |
| |
| } |
| System.out.println("下载完成"); |
| } finally { |
| if (is != null) { |
| is.close(); |
| } |
| if (os != null) { |
| os.close(); |
| } |
| } |
| } |
| |
| private final static long per_page = 1024l * 1024l * 50l; |
| |
| private final static String down_path = "D:\\File"; |
| |
| ExecutorService pool = Executors.newFixedThreadPool(10); |
| |
| |
| |
| |
| |
| @RequestMapping("/downloadFile") |
| public String downloadFile() throws IOException { |
| FileInfo fileInfo = download(0, 10, -1, null); |
| if (fileInfo != null) { |
| long pages = fileInfo.fSize / per_page; |
| for (int i = 0; i <= pages; i++) { |
| pool.submit(new Download(i * per_page, (i + 1) * per_page - 1, i, fileInfo.fName)); |
| } |
| } |
| |
| return "成功"; |
| } |
| |
| class Download implements Runnable { |
| long start; |
| long end; |
| long page; |
| String fName; |
| |
| public Download(long start, long end, long page, String fName) { |
| this.start = start; |
| this.end = end; |
| this.page = page; |
| this.fName = fName; |
| } |
| |
| @Override |
| public void run() { |
| try { |
| FileInfo fileInfo = download(start, end, page, fName); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| @RequestMapping("/download") |
| private FileInfo download(long start, long end, long page, String fName) throws IOException { |
| |
| File file = new File(down_path, page + "-" + fName); |
| |
| if (file.exists() && page != -1 && file.length() == per_page) { |
| return null; |
| } |
| |
| HttpClient client = HttpClients.createDefault(); |
| |
| HttpGet httpGet = new HttpGet("http://127.0.0.1:8080/down"); |
| |
| httpGet.setHeader("Range", "bytes=" + start + "-" + end); |
| HttpResponse response = client.execute(httpGet); |
| String fSize = response.getFirstHeader("fSize").getValue(); |
| fName = URLDecoder.decode(response.getFirstHeader("fName").getValue(), "utf-8"); |
| HttpEntity entity = response.getEntity(); |
| InputStream is = entity.getContent(); |
| |
| FileOutputStream fos = new FileOutputStream(file); |
| byte[] buffer = new byte[1024]; |
| int ch; |
| while ((ch = is.read(buffer)) != -1) { |
| fos.write(buffer, 0, ch); |
| } |
| is.close(); |
| fos.flush(); |
| fos.close(); |
| |
| if (end - Long.valueOf(fSize) > 0) { |
| |
| try { |
| mergeFile(fName, page); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| return new FileInfo(Long.valueOf(fSize), fName); |
| } |
| |
| private void mergeFile(String fName, long page) throws Exception { |
| |
| File file = new File(down_path, fName); |
| BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(file)); |
| for (int i = 0; i <= page; i++) { |
| File tempFile = new File(down_path, i + "-" + fName); |
| |
| while (!file.exists() || (i != page && tempFile.length() < per_page)) { |
| Thread.sleep(100); |
| } |
| byte[] bytes = FileUtils.readFileToByteArray(tempFile); |
| os.write(bytes); |
| os.flush(); |
| tempFile.delete(); |
| } |
| File file1 = new File(down_path, -1 + "-null"); |
| file1.delete(); |
| os.flush(); |
| os.close(); |
| } |
| |
| |
| class FileInfo { |
| long fSize; |
| String fName; |
| |
| public FileInfo(long fSize, String fName) { |
| this.fSize = fSize; |
| this.fName = fName; |
| } |
| } |
| |
| } |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端