SpringBoot 本地大文件分隔及其合并

2023-10-30

需求背景:公司前端反馈使用pdf.js 加载超大pdf 文件,会出现内存泄露的情况。需要后台给出优化的方案。

解决办法:将本地pdf 文件大于200M 的文件进行分隔。每个分隔文件大小为10M.

后台核心代码如下:

@RequestMapping(value = "/fileBlock")
	public ResponseEntity<String> fileBlock() throws IOException {
		// 定义分隔模块大小
		long blockSize = 10 * 1024 * 1024;
		// 动态计算分块总数
		long blockTotal = 0;
		// 读取目标的大文件
		File targetFile = new File("D:\\20180968600020001.pdf");
		RandomAccessFile raf = new RandomAccessFile(targetFile, "r");

		// 读取文件大小
		long fileSize = raf.length();
		// 动态计算分块大小
		if (fileSize % blockSize > 0) {
			blockTotal = fileSize / blockSize + 1;
		} else {
			blockTotal = fileSize / blockSize;
		}

		long offSet = 0L;// 初始化偏移量
		for (int i = 0; i < blockTotal; i++) { // 最后一片单独处理
			long begin = offSet;
			long end = (i + 1) * blockSize;
			// offSet = writeFile(file, begin, end, i);
			offSet = getWrite("D:\\20180968600020001.pdf", i, begin, end);
		}
		

	
		HttpHeaders headers = new HttpHeaders();
		return new ResponseEntity<String>("大文件分片成功", headers, HttpStatus.OK);
	}

	/**
     * 指定文件每一份的边界,写入不同文件中
     * @param file 源文件
     * @param index 源文件的顺序标识
     * @param begin 开始指针的位置
     * @param end 结束指针的位置
     * @return long
     */
    public static long getWrite(String file,int index,long begin,long end){
        String a=file.split(".pdf")[0];
        long endPointer = 0L;
        try {
            //申明文件切割后的文件磁盘
            RandomAccessFile in = new RandomAccessFile(new File(file), "r");
            //定义一个可读,可写的文件并且后缀名为.tmp的二进制文件
            RandomAccessFile out = new RandomAccessFile(new File(a + "_" + index + ".tmp"), "rw");
 
            //申明具体每一文件的字节数组
            byte[] b = new byte[1024];
            int n = 0;
            //从指定位置读取文件字节流
            in.seek(begin);
            //判断文件流读取的边界
            while(in.getFilePointer() <= end && (n = in.read(b)) != -1){
                //从指定每一份文件的范围,写入不同的文件
                out.write(b, 0, n);
            }
            //定义当前读取文件的指针
            endPointer = in.getFilePointer();
            //关闭输入流
            in.close();
            //关闭输出流
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return endPointer;
    }
    
    @RequestMapping(value = "/fileMerge")
	public ResponseEntity<String> fileMerge() throws IOException {
    	// 合并文件规则:先删后增
    	String filePath = "D:\\123456.pdf";
    	File targetFile = new File(filePath);
    	targetFile.delete();
    	targetFile.createNewFile();
    	
    	
		// 文件合并
    	this.merge(filePath, "D:\\20180968600020001.pdf", 3);

		
	
		HttpHeaders headers = new HttpHeaders();
		return new ResponseEntity<String>("大文件合并成功", headers, HttpStatus.OK);
	}
    
    /**
     * 文件合并
     * @param file 指定合并文件
     * @param tempFile 分割前的文件名
     * @param tempCount 文件个数
     */
    public static void merge(String file,String tempFile,int tempCount) {
        String a=tempFile.split(".pdf")[0];
        RandomAccessFile raf = null;
        try {
            //申明随机读取文件RandomAccessFile
            raf = new RandomAccessFile(new File(file), "rw");
            //开始合并文件,对应切片的二进制文件
            for (int i = 0; i < tempCount; i++) {
                //读取切片文件
                RandomAccessFile reader = new RandomAccessFile(new File(a + "_" + i + ".tmp"), "r");
                byte[] b = new byte[1024];
                int n = 0;
                //先读后写
                while ((n = reader.read(b)) != -1) {//读
                    raf.write(b, 0, n);//写
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                raf.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

效果截图:

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot 本地大文件分隔及其合并 的相关文章

随机推荐

  • 阿里云 Serverless 应用引擎 2.0,正式公测!

    阿里云 Serverless 应用引擎 SAE2 0 正式公测上线 全面升级后的 SAE2 0 具备极简体验 标准开放 极致弹性三大优势 应用冷启动全面提效 秒级完成创建发布应用 应用成本下降 40 以上 此外 阿里云还带来容器服务 Ser
  • 虚拟数字人定制公司 国内做虚拟数字人定制开发的公司有吗?

    得益于图形渲染技术 AI技术 传感器硬件等技术的发展 使得虚拟数字人逐步进入大众视野 虚拟数字人分为真人驱动 AI驱动 AI合成 不同形式的虚拟数字人制作难度与成本相差较大 许多大众认为 制作虚拟数字人就是做一个美术就可以了 如果这样的话
  • 相机标定系列---opencv相关标定算子

    目录 1 标定的相关介绍 2 算法流程及相关算子简介 1 算法流程主要有五部分 2 相关算子介绍 1 棋盘标定板查找角点 2 亚像素角点准确化 3 可视化角点 4 相机标定 5 误差计算 3 完整代码 1 标定的相关介绍 1 标定的目的 在
  • MSBuild version 与 ToolsVersion 的区别

    MSBuild version 是指MSBuild所在的Framework的版本 ToolsVersion 是指编译当前工程使用的版本 相当于MSBuild的 ToolsVersion 参数 如果一个MSBuild 脚本中 既含有Tools
  • 理解make update-api命令

    一 使用场景 增加系统API 修改 hide的API 修改公共API 存在以上修改后 都需要先执行make update api 然后再make 二 缘起 1 在以上使用场景下 编译系统源码都会出现如下提示 see build core a
  • Python——信号量、条件变量、事件

    1 信号量 Semaphore 信号量通常用于保护数量有限的资源 例如数据库服务器 在资源数量固定的任何情况下 都应该使用有界信号量 在生成任何工作线程前 应该在主线程中初始化信号量 信号量提供acquire方法和release方法 每当调
  • Summer Holiday HDU - 1827 Tarjian

    题目链接 HDU 1827 主要思路 先用Tarjian处理出强联通块 然后将每个点的边转为强联通块之间的边 然后连上一个个入度为0的强联通块中最小的结点即可 正确性解释 用Tarjian算法处理出强连通块之后把每个强联通块看成是一个点 故
  • 蓝牙模块AT模式AT指令

    文章目录 进入AT模式的两种方法 HC 05的AT指令 HC 06的AT指令 进入AT模式的两种方法 经过摸索 这里总结两种进入AT模式的方法 与USB转TTL相连后接入电脑 将波特率设置成9600 模块指示灯快闪 这时再按下模块的按钮便进
  • 解决idea中不能输出中文问题

    在CSDN上查明了问题 解决方法 gt gt gt gt gt 打开idea 点在左上角的File 找到Settings 点击找到File Encodings然后看上面的Global Encoding和Project Encoding 都选
  • 埋点理论以及基于Vue的前端埋点技术

    一 明确目标 要知道利用埋点获取数据是要做什么样的用户分析 二 获取数据 三 埋点技术 四 已有软件 五 声明式埋点的实现 利用Vue的自定义指令原理 比如下边监控按钮点击的埋点 在main js中定义全局自定义指令 Vue directi
  • 【springboot】解决springboot项目,扫描不到自定义的controller

    如果遇到 http localhost 8080 test访问出现这个异常This application has no explicit mapping for error so you are seeing this as a fall
  • ASP.Net+SQLserver部署到阿里云Windows版本服务器

    工具 1 阿里云云服务器ECS 2 Windows 7 专业版 3 Visual Studio 2017 4 SQL Server2008 R2 写在前面 网站建立好之后 部署在本地服务器 只能局域网内访问 如果想让外网可以访问该网站 我们
  • spring boot配置shiro安全框架及用户登录权限验证实现

    关于shiro的配置我单独拿出来写了 从数据库表建立 到配置 如何使用 连接地址为shiro安全框架 shiro的应用理解 如果有修改会在这里边修改的 另外 springboot shiro的项目已分享到GitHub上 如果需要的可以看下
  • Scratch3.0连接EV3,WEDO2.0的方法视频讲解。

    为什么讲这个问题 最近因为国内对Scratch服务器访问的限制 现在访问官网和链接Scratch服务器的功能模块都使用不成了 离线版本中EV3和WEDO链接上也出了问题 目前这个是可以解决的 这个问题怎么解决 其实主要还是修改电脑的host
  • linux服务器搭建心得

    安装显卡 非必要不去官网手动安装 容易出错 ubuntu 查看显卡 ubuntu drivers devices 根据输出安装 sudo apt install nvidia deiver xxx 重启 reboot 检查安装 nvidia
  • 队列实现栈(你看我讲的是不是最细的就完了)

    最伟大的成就往往起源于最强烈的热情 诺曼 文森特 皮尔目录 一 队列实现栈 二 使用两个队列来模拟实现栈 1 栈结构体包含两个队列 2 创建一个结构体的指针 3 myStackPush入栈操作 4 myStackPop出队列操作并返回剩下的
  • 【浙工商期末报告】研一Python期末作业B题(思路分享+源代码分享+原报告分享)

    目录 研一Python期末作业B题 思路分享 一 题目介绍 1 1 A题 1 2 B题 二 B题思路讲解 2 1 问题的引入 2 2 不平衡数据集 2 2 1 不平衡数据的实例 2 2 2 不平衡数据集导致的问题 2 2 3 不平衡数据集的
  • 完备的AI学习路线(三)基础知识之python编程

    入门人工智能领域 首推Python这门编程语言 1 Python安装 Python安装包 我推荐下载Anaconda Anaconda是一个用于科学计算的Python发行版 支持 Linux Mac Windows系统 提供了包管理与环境管
  • 搜索优化剪枝策略

    状态剪枝 如果将搜索的状态看作结点 状态之间的转移看作边 搜索的过程就构建出了一棵 搜搜树 其实 这也是判定搜索题目的一个方法 所谓 剪枝 就是在搜索树上去掉一些枝杈不进行搜索 从而减少小时间消耗 搜索树的剪枝如下图所示 常用的思考策略 1
  • SpringBoot 本地大文件分隔及其合并

    需求背景 公司前端反馈使用pdf js 加载超大pdf 文件 会出现内存泄露的情况 需要后台给出优化的方案 解决办法 将本地pdf 文件大于200M 的文件进行分隔 每个分隔文件大小为10M 后台核心代码如下 RequestMapping