文件下载OOM
File file = new File(filePath);// 几百兆的文件,直接拉到内存?byte[] data = Files.readAllBytes(file.toPath());
try (InputStream in = new FileInputStream(file);OutputStream out = new BufferedOutputStream(response.getOuptputStream())) {// 每次读1KBbyte[] buffer = new byte[1024];int len;while ((len = in.read(buffer)) != -1) {out.write(buffer, 0 ,len);}out.flush();} catch (IOExcepetion e) {throw new RuntimeException("下载失败", e);}
try (FileInputStream fis = new FileInputStream(file);FileChannel fileChannel = fis.getChannel()) {long position = 0;long size = fileChannel.size();WritableByteChannel writableChannel = Channels.newChannel(response.getOutputStream());// 每次传输最多8KB的倍数, 但 transferTo 会尽量利用 DMA一次传更多while (position < size) {long transfered = fileChannel.transferTo(position, sizd - position, writableChannel);if (transfered <= 0) break;position += transfered;}}
long fileLength = file.length();Sting fileName = URLEncoder.encode(file.getName(), StandardCharsets.UTF_8);String rangeHeader = request.getHeader("Range");long start = 0;long end = fileLength - 1;//解析 Range 头if (rangeHeader != null && rangeHeader.startsWith("bytes=")) {String rangeValue = rangeHeader.substring("bytes=".length());String[] parts = rangeValue.split("-");try {start = Long.parseLong(parts[0]);if (parts.length > 1 && !parts[1].isEmpty()) {end = Long.parseLong(parts[1]);}} catch (NumberFormatException e) {response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);return;}if (start < 0 || start > end || end >= fileLength) {response.setStatus(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);return;}}
夜雨聆风