springboot服务器文件读取工具类

ops/2024/10/21 11:55:28/

本地文件和网络文件读取

一. SpringBoot的RestTemplate配置

  • RestTemplate

二. 文件读取

  • RangeEntity 分片下载的封装对象
java">package com.zzc.component.download;import com.zzc.common.utils.StrUtils;
import lombok.Data;import javax.servlet.http.HttpServletResponse;public class RangeEntity {private String range;private long contentLength;private String contentRange;private Long firstPos;private Long lastPos;public RangeEntity(String range, long contentLength) {parseRange(range, contentLength);}private void parseRange(String range, long contentLength) {this.range = range;this.contentLength = contentLength;if (StrUtils.isBlank(range) || "null".equalsIgnoreCase(range)) {this.firstPos = 0L;this.contentLength = contentLength;this.contentRange = "bytes " + 0 + "-" + (contentLength - 1) + "/" + contentLength;return;}range = range.trim();String rangeBytes = range.replaceAll("bytes=", "").replaceAll(" ", "");if (rangeBytes.endsWith("-")) {//bytes=99999-rangeBytes = rangeBytes.substring(0, rangeBytes.indexOf("-"));this.firstPos = Long.valueOf(rangeBytes.trim());this.contentLength = contentLength - this.firstPos;this.contentRange = "bytes " + this.firstPos + "-" + (contentLength - 1) + "/" + contentLength;} else {this.firstPos = Long.valueOf(rangeBytes.substring(0, rangeBytes.indexOf("-")));this.lastPos = Long.valueOf(rangeBytes.substring(rangeBytes.indexOf("-") + 1));this.contentLength = this.lastPos - this.firstPos + 1;this.contentRange = "bytes " + this.firstPos + "-" + this.lastPos + "/" + contentLength;}}public int getStatusCode(boolean isIeOrPlayer) {if (((StrUtils.isBlank(range) || "null".equalsIgnoreCase(range)) && isIeOrPlayer)|| (this.firstPos == null && this.lastPos == null)) {return HttpServletResponse.SC_OK;} else {return HttpServletResponse.SC_PARTIAL_CONTENT;}}public String getRange() {return range;}public long getContentLength() {return contentLength;}public String getContentRange() {return contentRange;}public boolean isNotRange() {return lastPos == null || firstPos == 0;}public Long getFirstPos() {return firstPos;}
}
  • HeaderUtils 请求header判断类
java">package com.zzc.component.download;import com.zzc.common.utils.StrUtils;import javax.servlet.http.HttpServletRequest;public class HeaderUtils {public static boolean isIeBrowser(HttpServletRequest request) {String[] isSignals = {"MSIE", "Trident", "Edge", "Safari"};String userAgent = request.getHeader("User-Agent");if (StrUtils.isNotBlank(userAgent)) {for (String signal : isSignals) {if (userAgent.contains(signal)) {return true;}}}return false;}public static boolean isWinPlayer(HttpServletRequest request) {String userAgent = request.getHeader("User-Agent");if (StrUtils.isNotBlank(userAgent)) {return userAgent.contains("Windows-Media-Player");}return false;}
}
  • HeaderConstant请求header对应字段
java">package com.zzc.component.download;public class HeaderConstant {public static final String KEY_ACCEPT_RANGE = "Accept-Ranges";public static final String KEY_CONTENT_LENGTH = "Content-Length";public static final String KEY_CONTENT_RANGE = "Content-Range";public static final String KEY_CONTENT_TYPE = "Content-Type";public static final String KEY_CONTENT_DISPOSITION = "Content-Disposition";
}
java">package com.zzc.component.download;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public interface FileComponent {void play(String path, HttpServletRequest request, HttpServletResponse response);void download(String path, HttpServletRequest request, HttpServletResponse response);}
java">package com.zzc.component.download;import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;@Slf4j
@Component
public class FileComponentImpl implements FileComponent {@Overridepublic void play(String path, HttpServletRequest request, HttpServletResponse response) {RandomAccessFile raf = null;try {File file = new File(path);if (!file.exists()) {throw new RuntimeException();}long length = file.length();String range = request.getHeader("Range");String filename = file.getName();String contentType = "video/mp4";//文件类型RangeEntity rangeEntity = new RangeEntity(range, length);addHeader(request, response, rangeEntity, contentType, filename);raf = new RandomAccessFile(file, "r");OutputStream outputStream = response.getOutputStream();if (rangeEntity.isNotRange()) {channelCopy(raf.getChannel(), Channels.newChannel(outputStream), rangeEntity.getFirstPos(), length);outputStream.flush();return;}long contentLength = rangeEntity.getContentLength();channelCopy(raf.getChannel(), Channels.newChannel(outputStream), rangeEntity.getFirstPos(), contentLength);outputStream.flush();//outputStream.close();} catch (Exception e) {} finally {if (raf != null) {try {raf.close();} catch (IOException e) {}}}}private static void addHeader(HttpServletRequest request, HttpServletResponse response, RangeEntity rangeEntity, String contentType, String filename) {boolean isIeOrPlayer = HeaderUtils.isWinPlayer(request) || HeaderUtils.isIeBrowser(request);response.setStatus(rangeEntity.getStatusCode(isIeOrPlayer));response.setHeader(HeaderConstant.KEY_ACCEPT_RANGE, "bytes");response.setHeader(HeaderConstant.KEY_CONTENT_LENGTH, rangeEntity.getContentLength() + "");if (rangeEntity.getContentRange() != null) {response.setHeader(HeaderConstant.KEY_CONTENT_RANGE, rangeEntity.getContentRange());}response.setHeader(HeaderConstant.KEY_CONTENT_TYPE, contentType);//response.setHeader(HeaderConstant.KEY_CONTENT_DISPOSITION, "inline; filename=\"" + filename + "\"; filename*=utf-8''" + filename);if (isIeOrPlayer) {try {response.setHeader(HeaderConstant.KEY_CONTENT_DISPOSITION, "inline; filename=\"" + URLEncoder.encode(filename, "UTF-8"));} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}}}@Overridepublic void download(String path, HttpServletRequest request, HttpServletResponse response) {FileInputStream is = null;try {File file = new File(path);if (!file.exists()) {throw new RuntimeException();}String name = file.getName();long length = file.length();String contentType = "video/mp4";is = new FileInputStream(file);response.setHeader(HeaderConstant.KEY_CONTENT_LENGTH,  length + "");response.setHeader(HeaderConstant.KEY_CONTENT_TYPE, contentType);response.setHeader(HeaderConstant.KEY_CONTENT_DISPOSITION, "attachment;filename=" + name);ServletOutputStream outputStream = response.getOutputStream();channelCopy(is.getChannel(), Channels.newChannel(outputStream), 0, length);outputStream.flush();outputStream.close();} catch (Exception e) {} finally {if (is != null) {try {is.close();} catch (IOException e) {}}}}private static void channelCopy(FileChannel readableChannel, WritableByteChannel writableByteChannel, long position, long size) {try {if (writableByteChannel.isOpen()) {readableChannel.transferTo(position, size, writableByteChannel);}} catch (Exception e) {} finally {try {readableChannel.close();writableByteChannel.close();} catch (IOException e) {}}}
}
java">package com.zzc.component.download;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public interface OBSComponent {void download(String url, HttpServletRequest request, HttpServletResponse response);}
java">package com.zzc.component.download;import com.zzc.component.http.RestTemplateComponent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.client.ResponseExtractor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.HashMap;
import java.util.Map;@Slf4j
@Component
public class OBSComponentImpl implements OBSComponent {@Autowiredprivate RestTemplateComponent restTemplateComponent;@Overridepublic void download(String url, HttpServletRequest request, HttpServletResponse response) {Map<String, String> headers = new HashMap<>();ResponseExtractor<Boolean> extractor = new ResponseExtractor<Boolean>() {@Overridepublic Boolean extractData(ClientHttpResponse clientHttpResponse) throws IOException {HttpStatus statusCode = clientHttpResponse.getStatusCode();if (statusCode.isError()) {return false;}//TODO headMap<String, String> header = new HashMap<>();return true;}};restTemplateComponent.transfer(url, headers, extractor);}private static void channelCopy(ReadableByteChannel readableByteChannel, WritableByteChannel writableByteChannel) {try {ByteBuffer buffer = ByteBuffer.allocateDirect(32 * 1024);while (writableByteChannel.isOpen() && readableByteChannel.read(buffer) != -1) {buffer.flip();writableByteChannel.write(buffer);buffer.compact();}buffer.flip();while (writableByteChannel.isOpen() && buffer.hasRemaining()) {writableByteChannel.write(buffer);}} catch (Exception e) {} finally {try {readableByteChannel.close();writableByteChannel.close();} catch (IOException e) {}}}
}

http://www.ppmy.cn/ops/106465.html

相关文章

go程序解说

Go&#xff08;通常称为 Golang&#xff09;是一种开源的编程语言&#xff0c;由 Google 开发&#xff0c;于 2009 年首次发布。 Go 语言的设计目标是结合 C 语言的性能和效率以及现代编程语言的高级特性&#xff0c;如垃圾回收、类型安全和并发控制。 Go 语言以其简洁、高效…

Spring Cloud Gateway的使用

Spring Cloud Gateway的使用 1. Spring Cloud Gateway原理2. Spring Boot项目中集成Spring Cloud Gateway2.1 创建项目与添加依赖2.2 配置网关 3. 高级功能与实践**3.1 配置过滤器****3.2 分组路由** 4. 监控与故障处理5. 部署与持续集成 在微服务架构中&#xff0c;服务发现、…

spring boot(学习笔记第十九课)

spring boot(学习笔记第十九课) Spring boot的batch框架&#xff0c;以及Swagger3(OpenAPI)整合 学习内容&#xff1a; Spring boot的batch框架Spring boot的Swagger3&#xff08;OpenAPI&#xff09;整合 1. Spring boot batch框架 Spring Batch是什么 Spring Batch 是一个…

安卓逆向(之)真机root(红米手机)

概览&#xff1a; 1, 手机解锁 2, 下载官方系统包&#xff0c;推荐线刷包,取出镜像文件 3, magisk工具修补 官方系统包 4, adb&#xff1a;命令对手机刷 root 5, 完成 6, 小米手机解锁 点击 小米手机解锁OEM官方教程 记得数据线连接手机电脑 工具下载 点击 下载adb(电脑操作…

【Redis】Redis 主从复制原理与配置详解:解决单点故障与性能瓶颈的最佳方案

目录 主从复制配置建立复制断开复制安全性只读传输延迟 拓扑⼀主⼀从结构一主多从结构树形主从结构 原理复制过程数据同步 psync全量复制部分复制实时复制 小结 主从复制 这部分相关操作不需要记忆!!! 后续⼯作中如果⽤到了能查到即可. 重点理解流程和原理. 单点问题&#xff1…

ChatGPT付费创作系统V3.0.6独立版 WEB+H5+小程序端 (新增AI全网搜索+文档解析+豆包AI通道)安装部署教程

播播资源GPT付费体验系统最新版系统是一款基于ThinkPHP框架开发的AI问答小程序&#xff0c;是基于国外很火的ChatGPT进行开发的Ai智能问答小程序。这是一种基于人工智能技术的问答系统&#xff0c;可以实现智能回答用户提出的问题。相比传统的问答系统&#xff0c;ChatGPT可以更…

Python知识点:如何使用Python实现自动驾驶模拟

在 Python 中实现自动驾驶模拟&#xff0c;通常需要使用特定的仿真环境和工具库&#xff0c;以帮助处理感知、决策和控制等方面。这里是一个基本的流程和所需工具的介绍。 1. 选择仿真环境 常见的自动驾驶仿真环境包括&#xff1a; CARLA&#xff1a;开源自动驾驶模拟器&…

如何用 Typed.js 制作炫酷的打字效果?

前言 在前端开发的世界中&#xff0c;动态和交互性是用户体验的关键。 Typed.js 是一个轻量级的 JavaScript 库&#xff0c;它能够以编程方式模拟打字效果&#xff0c;为网页增添动态的文本展示。 这篇文章将带你深入了解 Typed.js 的魔力&#xff0c;探索它如何为前端开发带…