关于文件分片的介绍和应用
文件分片,顾名思义,就是将一个大文件分割成多个小的文件块(chunk)。每个文件块都是原始文件的一部分,并可以通过特定的方式将这些小文件块重新组装成原始文件。
1. 基本原理:
文件分片从底层来看,主要是对文件进行字节级别的读取和分割。可以将文件看作一个巨大的字节数组,分片的过程就是按照一定的规则将这个字节数组切割成多个小数组,然后将每个小数组写入到不同的文件中。
-
定义分片大小 (Chunk Size): 这是核心参数。所有的分片都会被切割成这个大小 (最后一个分片可能小于这个大小).
-
读取文件: 用二进制方式读取文件.
-
分割数据: 根据
Chunk Size
,将读取到的文件内容分割成多个字节数组. -
写入分片文件: 每个字节数组 (chunk) 被写入到单独的文件中。 通常,会为每个分片文件命名,以便后续可以按顺序组装它们。
-
元数据:在分片的同时,通常会生成一个元数据文件,其中包含原始文件名、分片数量、每个分片的顺序和大小等信息。这个元数据文件是后续重新组装文件的关键。
2. 关键技术:
-
文件读取: 使用
InputStream
或FileChannel
等进行二进制文件读取.FileChannel
通常提供更高的性能. -
字节数组操作: 使用
byte[]
来存储和操作文件数据. -
文件写入: 使用
OutputStream
或FileChannel
将字节数组写入到各个分片文件中。同样的,FileChannel
通常有更好的性能。 -
偏移量 (Offset): 在读取和写入过程中,需要记录每个分片的起始位置(偏移量),以便正确地分割和组装文件。
3.参考代码(来源于练习项目)
package com.frontend.file;import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.stream.Stream;public class FileMerger{private static final String tempFilePath = "D:/data/project/com.frontEndProject/temp/download";private static final String userFilePath ="D:/data/project/com.frontEndProject/userFile";private final String inputFolder;private final String outputFolder;private final String fileName;public FileMerger(String inputFolder, String outputFolder, String fileName) {this.inputFolder = inputFolder;this.outputFolder = outputFolder;this.fileName = fileName;}public Path mergeFiles() throws IOException {Path chunkPath= Paths.get(tempFilePath+"/"+inputFolder);Path parentDir=Paths.get(userFilePath+"/"+outputFolder);Path saveFilePath=Paths.get(userFilePath+"/"+outputFolder+"/"+fileName);if(!Files.exists(chunkPath)){Files.createDirectories(chunkPath);}if(!Files.exists(parentDir)){Files.createDirectories(parentDir);}if(!Files.exists(saveFilePath)){Files.createFile(saveFilePath);}try(Stream<Path> paths = Files.list(chunkPath).sorted(Comparator.comparing(p->p.getFileName().toString()))){try(FileOutputStream fos=new FileOutputStream(saveFilePath.toFile()); BufferedOutputStream bos=new BufferedOutputStream(fos)){paths.forEach(chunkFile->{try(FileInputStream fis=new FileInputStream(chunkFile.toFile()); BufferedInputStream bis=new BufferedInputStream(fis)) {byte[] buffer=new byte[8192];int bytesRead;while((bytesRead=bis.read(buffer))!=-1){bos.write(buffer,0,bytesRead);}} catch (IOException e) {throw new RuntimeException(e);}});}}return saveFilePath;}
}
package com.frontend.file;import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.util.Comparator;
import java.util.stream.Stream;public class FileSplitter{private static final String tempFilePath = "D:/data/project/com.frontEndProject/temp/upload";private final File sourceFile;private final String outputFolder;private final int chunkSize;public FileSplitter(File sourceFile, String outputFolder, int chunkSize){this.sourceFile = sourceFile;this.outputFolder = outputFolder;this.chunkSize = chunkSize;}public Stream<Path> splitFile() throws IOException {Path outputPath = Paths.get(tempFilePath +"/"+outputFolder);if(!Files.exists(outputPath)){Files.createDirectories(outputPath);}try(FileInputStream fis = new FileInputStream(sourceFile); BufferedInputStream bis = new BufferedInputStream(fis)){byte[] buffer=new byte[chunkSize];int index=0,bytesRead;String fileHash= FileHash.calculateHash(sourceFile,"SHA-256");while ((bytesRead=bis.read(buffer))!=-1){String chunkFileName=String.format("%s%06d.temp",fileHash,++index);Path tempFilePath=outputPath.resolve(chunkFileName);if(Files.exists(tempFilePath))continue;try(FileOutputStream fos = new FileOutputStream(tempFilePath.toFile()); BufferedOutputStream bos = new BufferedOutputStream(fos)){bos.write(buffer,0,bytesRead);}}} catch (NoSuchAlgorithmException e) {throw new RuntimeException(e);}Stream<Path> result;try {result =Files.list(outputPath).sorted(Comparator.comparing(p->p.getFileName().toString()));} catch (IOException e) {throw new RuntimeException(e);}return result;}
}
package com.frontend.file;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class FileHash{public static String calculateHash(File file, String algorithm) throws NoSuchAlgorithmException, IOException, IOException {MessageDigest messageDigest= MessageDigest.getInstance(algorithm);try(FileInputStream fr=new FileInputStream(file)){byte[] buffer=new byte[8192];int readBytes;while ((readBytes=fr.read(buffer))!=-1){messageDigest.update(buffer,0,readBytes);}}byte[] digest=messageDigest.digest();StringBuilder stringBuilder=new StringBuilder();for(byte b:digest){stringBuilder.append(String.format("%02x",b));}return stringBuilder.toString();}public static boolean VerifyFileHash(String fileHash, String saveRecordFilePath) throws IOException, NoSuchAlgorithmException {File file = new File(saveRecordFilePath);if(!file.exists()) return false;String verifyFileHash=calculateHash(Paths.get(saveRecordFilePath).toFile(),"SHA-256");return verifyFileHash.equals(fileHash);}public static void main(String[] args) throws NoSuchAlgorithmException, IOException {Path filePath= Paths.get("D:\\code\\Java\\frontEndProject\\src\\main\\java\\com\\frontend\\controller\\EditorialMaterialController.java");String result=calculateHash(filePath.toFile(),"SHA-256");System.out.println(result.length());}
}
相关文章:
关于文件分片的介绍和应用
文件分片,顾名思义,就是将一个大文件分割成多个小的文件块(chunk)。每个文件块都是原始文件的一部分,并可以通过特定的方式将这些小文件块重新组装成原始文件。 1. 基本原理: 文件分片从底层来看,主要是对…...

Tapered Off-Policy REINFORCE_ 如何为LLM实现稳定高效的策略优化?
Tapered Off-Policy REINFORCE: 如何为LLM实现稳定高效的策略优化? 在大语言模型(LLM)的微调领域,强化学习(RL)正成为提升复杂任务性能的核心方法。本文聚焦于一篇突破性论文,其提出的Tapered …...
使用lvm进行磁盘分区
使用lvm进行磁盘分区 目的: 使用/dev/vdb创建一个5g的逻辑卷挂载到/mnt/lvmtest 前提: /dev/vdb是一块干净的空磁盘,数据会被清空!!! 1. 创建物理卷(PV): pvcreate /dev/sdb2. 验证…...

[Java实战]Spring Boot整合Elasticsearch(二十六)
[Java实战]Spring Boot整合Elasticsearch(二十六) 摘要:本文通过完整的实战演示,详细讲解如何在Spring Boot项目中整合Elasticsearch,实现数据的存储、检索和复杂查询功能。包含版本适配方案、Spring Data Elasticsea…...

图像分割(1)U-net
一、整体结构 虽然说是几年前的产品,但是现在还在用,因为深度学习很多时候越是简单的网络用起来效果越好,而且一般是目标比较小的时候产生的分割问题。u-net的优势就是网络结构简单,适合小目标分割,所以一直用到现在&a…...
数位和:从定义到编程实现
1. 定义 数位和(Digit Sum)是指一个数的每一位数字相加的总和。例如: 123 的数位和:1 2 3 645 的数位和:4 5 9 2. 计算方法 计算数位和的通用步骤: 提取每一位数字:从右到左&…...

2025抓包工具Reqable手机抓包HTTPS亲测简单好用-快速跑通
前言 自安卓7.0高版本系统不在信任用户证书,https抓包方式市面查找方法太过复杂手机要root等,前置条件要求太高太复杂,看的头痛,今天一台电脑按步骤操作完即可抓包https,给大家搞定抓包https问题。支持直接编辑修改请求参…...

使用 Auto-Keras 进行自动化机器学习
使用 Auto-Keras 进行自动化机器学习 了解自动化机器学习以及如何使用 auto-keras 完成它。如今,机器学习并不是一个非常罕见的术语,因为像 DataCamp、Coursera、Udacity 等组织一直在努力提高他们的效率和灵活性,以便将机器学习的教育带给普…...
python 自动化教程
文章目录 前言整数变量字符串变量列表变量算术操作比较操作逻辑操作if语句for循环遍历列表while循环定义函数调用函数导入模块使用模块中的函数启动Chrome浏览器打开网页定位元素并输入内容提交表单关闭浏览器发送GET请求获取网页内容使…...

简单使用Slidev和PPTist
简单使用Slidev和PPTist 1 简介 前端PPT制作有很多优秀的工具包,例如:Slidev、revealjs、PPTist等,Slidev对Markdown格式支持较好,适合与大模型结合使用,选哟二次封装;revealjs适合做数据切换,…...

RISC-V 开发板 MUSE Pi Pro V2D图像加速器测试,踩坑介绍
视频讲解: RISC-V 开发板 MUSE Pi Pro V2D图像加速器测试,踩坑介绍 今天测试下V2D,这是K1特有的硬件级别的2D图像加速器,参考如下文档,但文档中描述的部分有不少问题,后面会讲下 https://bianbu-linux.spa…...
人工智能100问☞第26问:什么是贝叶斯网络?
贝叶斯网络是基于有向无环图和条件概率表构建的概率图模型,用于表达变量间的条件依赖关系并进行不确定性推理。 一、通俗解释 想象你玩侦探游戏,要通过零散线索推理真相。贝叶斯网络就像一张"因果关系地图"——用箭头把事件连起来,并标注每个事件发生的概率。比…...

c++多线程debug
debug demo 命令行查看 ps -eLf|grep cam_det //查看当前运行的轻量级进程 ps -aux | grep 执行文件 //查看当前运行的进程 ps -aL | grep 执行文件 //查看当前运行的轻量级进程 pstree -p 主线程ID //查看主线程和新线程的关系 查看线程栈结构 pstack 线程ID 步骤&…...

如何畅通需求收集渠道,获取用户反馈?
要畅通需求收集渠道、有效获取用户反馈,核心在于多样化反馈入口、闭环反馈机制、用户分层管理、反馈数据结构化分析等四个方面。其中,多样化反馈入口至关重要,不同用户有不同的沟通偏好,只有覆盖多个反馈路径,才能捕捉…...
标准库、HAl库和LL库(PC13初始化)
标准库 (Standard Peripheral Library) c #include "stm32f10x.h"void GPIO_Init_PC13(void) {GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);GPIO_InitStruct.GPIO_Pin GPIO_Pin_13;GPIO_InitStruct.GPIO_Mode GPIO_…...
LangGraph深度解析:构建持久化、可观测的智能体工作流
一、项目概述与技术定位 1.1 LangGraph核心价值 LangGraph是由LangChain团队推出的开源框架(GitHub仓库:https://github.com/langchain-ai/langgraph),专为构建持久化、状态化的智能体工作流设计。作为LangChain生态系统的战略补充,它解决了传统LLM应用在以下方面的关键…...

设备预测性维护的停机时间革命:中讯烛龙如何用AI重构工业设备管理范式
在工业4.0的智能化浪潮中,非计划停机每年吞噬企业3%-8%的产值。中讯烛龙预测性维护系统通过多模态感知矩阵分布式智能体的创新架构,实现设备健康管理的范式跃迁,帮助制造企业将停机时间压缩70%以上。本文将深度解析技术实现路径与行业级实践方…...
day29 python深入探索类装饰器
目录 一、类装饰器的初步理解 二、类装饰器与函数装饰器的对比 三、类装饰器的实现与应用 (一)为类添加日志功能 (二)动态方法绑定的两种方式 四、手动调用装饰器:类的“后天改造” 五、总结与展望 一、类装饰器…...

Python数据分析三剑客:NumPy、Pandas与Matplotlib安装指南与实战入门
Python数据分析三剑客:NumPy、Pandas与Matplotlib安装指南与实战入门 1. 引言 Python数据分析生态:NumPy、Pandas、Matplotlib是数据科学领域的核心工具链。适用场景:数值计算、数据处理、可视化分析(如金融分析、机器学习、科研…...
二:操作系统之进程控制块(PCB)
进程的身份证与状态记录:深入理解进程控制块 (PCB) 在我们之前的博客中,我们探讨了进程是什么——程序的一次执行实例,以及进程在其生命周期中会经历的各种状态(新建、就绪、运行、等待、终止)。我们知道,…...

Spring-Beans的生命周期的介绍
目录 1、Spring核心组件 2、Bean组件 2.1、Bean的定义 2.2、Bean的生命周期 1、实例化 2、属性填充 3、初始化 4、销毁 2.3、Bean的执行时间 2.4、Bean的作用域 3、常见问题解决方案 4、与Java对象区别 前言 关于bean的生命周期,如下所示: …...

Android 自定义悬浮拖动吸附按钮
一个悬浮的拨打电话按钮,使用CardViewImageView可能会出现适配问题,也就是图片显示不全,出现这种问题,就直接替换控件了,因为上述的组合控件没有FloatingActionButton使用方便,还可以有拖动和吸附效果不是更…...
通过串口设备的VID PID动态获取串口号(C# C++)
摘要 本篇文章主要介绍分别通过C#和C++使用设备VID PID如何动态获取COM口 目录 1 简述 2 VID PID查看方式 3 C#实现通过串口设备的VID PID动态获取串口号 3.1 辅助类实现 3.2 调用实例 4 C++实现通过串口设备的VID PID动态获取串口号 4.1 辅助类实现 4.2 调用实例 1 简…...
[创业之路-361]:企业战略管理案例分析-2-战略制定-使命、愿景、价值观的失败案例
一、失败案例 1、使命方面的失败案例 真功夫创业者内乱:真功夫在创业过程中,由于股权结构不合理,共同创始人及公司大股东潘宇海与实际控制人、董事长蔡达标产生管理权矛盾。双方在公司发展方向、管理改革等方面无法达成一致,导致…...
Window远程连接Linux桌面版
Window远程连接Linux桌面版 卸载RealVNC Server 一、确认是否安装了 VNC Server 先检查是否已安装: which vncserver # 或 dpkg -l | grep vnc # 或 rpm -qa | grep vnc二、在 Debian / Ubuntu 上卸载(.deb 安装) 1. 卸载 RealVNC Serve…...

一种开源的高斯泼溅实现库——gsplat: An Open-Source Library for Gaussian Splatting
一种开源的高斯泼溅实现库——gsplat: An Open-Source Library for Gaussian Splatting 文章目录 一种开源的高斯泼溅实现库——gsplat: An Open-Source Library for Gaussian Splatting摘要Abstract1. 基本思想1.1 设计1.2 特点 2. Nerfstudio&Splatfacto2.1 Nerfstudio2.…...

ARM A64 STR指令
ARM A64 STR指令 1 STR (immediate)1.1 Post-index1.1.1 32-bit variant1.1.2 64-bit variant 1.2 Pre-index1.2.1 32-bit variant1.2.2 64-bit variant 1.3 Unsigned offset1.3.1 32-bit variant1.3.2 64-bit variant 1.4 Assembler symbols 2 STR (register)2.1 32-bit varia…...
C#中的成员常量:编译时的静态魔法
在C#编程中,常量(const)是一个强大而特殊的语言特性,特别是当它们作为类的成员时。本文将深入探讨成员常量的特性、使用场景以及与静态量的区别。 成员常量的基本特性 成员常量是声明在类内部的常量,具有以下核心特点: 声明位置…...

Linux wlan 单频段 dual wifi创建
环境基础 TP LINK WN722N V1网卡linux 主机 查看设备是否支持双ap managed:客户端模式(连接路由器/AP)AP:接入点模式(创建热点)AP/VLAN:支持带VLAN标签的虚拟AP{ AP, mesh point, P2P-GO } &l…...
HOW - React NextJS 的同构机制
文章目录 一、什么是 Next.js 的同构?二、核心目录结构三、关键函数:如何实现不同渲染方式?1. getServerSideProps —— 实现 SSR(每次请求动态获取数据)2. getStaticProps getStaticPaths —— 实现 SSG(…...