minio 分布式文件系统 进阶
minio官网
英文:MinIO | S3 & Kubernetes Native Object Storage for AI
中文:MinIO | 用于AI的S3 & Kubernetes原生对象存储
1.Minio快速入门
http://t.csdnimg.cn/UVQmnhttp://t.csdnimg.cn/UVQmn
2.引入minio的依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.4.3</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.8.1</version>
</dependency>
3.(图片)文件分块和文件合并的基本实现:
-
testChunk
方法实现了大文件分块的功能。它首先定义了源文件(待分块的文件),分块文件的存储路径,分块文件的大小,然后计算出分块文件的个数。接着,使用RandomAccessFile
类从源文件中读取数据,并向分块文件中写入数据。最后,关闭文件流。 -
testMerge
方法实现了分块文件的合并功能。它首先定义了块文件目录,源文件和合并后的文件。然后,取出所有分块文件,将它们排序,接着使用RandomAccessFile
类从分块文件中读取数据,并向合并后的文件中写入数据。最后,关闭文件流,并对合并后的文件进行md5校验,如果校验成功,则输出“文件合并成功”
//分块测试
@Test
public void testChunk() throws IOException {
//源文件
File sourceFile = new File("D:\\develop\\upload\\1.项目背景.mp4");
//分块文件存储路径
String chunkFilePath = "D:\\develop\\upload\\chunk\\";
//分块文件大小
int chunkSize = 1024 * 1024 * 5;
//分块文件个数
int chunkNum = (int) Math.ceil(sourceFile.length() * 1.0 / chunkSize);
//使用流从源文件读数据,向分块文件中写数据
RandomAccessFile raf_r = new RandomAccessFile(sourceFile, "r");
//缓存区
byte[] bytes = new byte[1024];
for (int i = 0; i < chunkNum; i++) {
File chunkFile = new File(chunkFilePath + i);
//分块文件写入流
RandomAccessFile raf_rw = new RandomAccessFile(chunkFile, "rw");
int len = -1;
while ((len=raf_r.read(bytes))!=-1){
raf_rw.write(bytes,0,len);
if(chunkFile.length()>=chunkSize){
break;
}
}
raf_rw.close();
}
raf_r.close();
}
//将分块进行合并
@Test
public void testMerge() throws IOException {
//块文件目录
File chunkFolder = new File("D:\\develop\\upload\\chunk");
//源文件
File sourceFile = new File("D:\\develop\\upload\\1.项目背景.mp4");
//合并后的文件
File mergeFile = new File("D:\\develop\\upload\\1.项目背景_2.mp4");
//取出所有分块文件
File[] files = chunkFolder.listFiles();
//将数组转成list
List<File> filesList = Arrays.asList(files);
//对分块文件排序
Collections.sort(filesList, new Comparator<File>() {
@Override
public int compare(File o1, File o2) {
return Integer.parseInt(o1.getName())-Integer.parseInt(o2.getName());
}
});
//向合并文件写的流
RandomAccessFile raf_rw = new RandomAccessFile(mergeFile, "rw");
//缓存区
byte[] bytes = new byte[1024];
//遍历分块文件,向合并 的文件写
for (File file : filesList) {
//读分块的流
RandomAccessFile raf_r = new RandomAccessFile(file, "r");
int len = -1;
while ((len=raf_r.read(bytes))!=-1){
raf_rw.write(bytes,0,len);
}
raf_r.close();
}
raf_rw.close();
//合并文件完成后对合并的文件md5校验
FileInputStream fileInputStream_merge = new FileInputStream(mergeFile);
FileInputStream fileInputStream_source = new FileInputStream(sourceFile);
String md5_merge = DigestUtils.md5Hex(fileInputStream_merge);
String md5_source = DigestUtils.md5Hex(fileInputStream_source);
if(md5_merge.equals(md5_source)){
System.out.println("文件合并成功");
}
}
4.(视频)Minio对视频文件的操作
上传视频文件:
在上传分块时会检查分块到底上传传还是没有上传;
如果已经上传,那么服务端就会反馈已存在,这时就不会上传这个分块了。
如果没有上传该分块,则会上传到服务端,然后再上传到Minio。
当上传完成后,媒资服务发起合并分块的请求,请求Minio来合并分块,合并完成后,媒资服务向数据库保存信息。
FileInputStream和FilterInputStream的区别:
-
FileInputStream:
- 提供基本的文件读取操作,如读取单个字节、字节数组等。
- 不提供缓冲功能,频繁的读取操作可能会影响性能。
-
FilterInputStream:
- 本身不提供数据源,需要结合其他输入流使用。
- 提供了扩展功能,如
BufferedInputStream
可以提供缓冲功能,减少读取操作的次数,提高效率。
代码:
MinioClient minioClient =
MinioClient.builder()
.endpoint("http://192.168.101.65:9000")
.credentials("minioadmin", "minioadmin")
.build();
@Test
public void test_upload() throws Exception {
//通过扩展名得到媒体资源类型 mimeType
//根据扩展名取出mimeType
ContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(".mp4");
String mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;//通用mimeType,字节流
if(extensionMatch!=null){
mimeType = extensionMatch.getMimeType();
}
//上传文件的参数信息
UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder()
.bucket("testbucket")//桶
.filename("D:\\develop\\upload\\1.mp4") //指定本地文件路径
// .object("1.mp4")//对象名 在桶下存储该文件
.object("test/01/1.mp4")//对象名 放在子目录下
.contentType(mimeType)//设置媒体文件类型
.build();
//上传文件
minioClient.uploadObject(uploadObjectArgs);
}
//删除文件
@Test
public void test_delete() throws Exception {
//RemoveObjectArgs
RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket("testbucket").object("1.mp4").build();
//删除文件
minioClient.removeObject(removeObjectArgs);
}
//查询文件 从minio中下载
@Test
public void test_getFile() throws Exception {
GetObjectArgs getObjectArgs = GetObjectArgs.builder().bucket("testbucket").object("test/01/1.mp4").build();
//查询远程服务获取到一个流对象
FilterInputStream inputStream = minioClient.getObject(getObjectArgs);
//指定输出流
FileOutputStream outputStream = new FileOutputStream(new File("D:\\develop\\upload\\1a.mp4"));
IOUtils.copy(inputStream,outputStream);
//校验文件的完整性对文件的内容进行md5
FileInputStream fileInputStream1 = new FileInputStream(new File("D:\\develop\\upload\\1.mp4"));
String source_md5 = DigestUtils.md5Hex(fileInputStream1);
FileInputStream fileInputStream = new FileInputStream(new File("D:\\develop\\upload\\1a.mp4"));
String local_md5 = DigestUtils.md5Hex(fileInputStream);
if(source_md5.equals(local_md5)){
System.out.println("下载成功");
}
}
//将分块文件上传到minio
@Test
public void uploadChunk() throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
for (int i = 0; i < 6; i++) {
//上传文件的参数信息
UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder()
.bucket("testbucket")//桶
.filename("D:\\develop\\upload\\chunk\\"+i) //指定本地文件路径
.object("chunk/"+i)//对象名 放在子目录下
.build();
//上传文件
minioClient.uploadObject(uploadObjectArgs);
System.out.println("上传分块"+i+"成功");
}
}
//调用minio接口合并分块
@Test
public void testMerge() throws Exception {
// List<ComposeSource> sources = new ArrayList<>();
// for (int i = 0; i < 30; i++) {
// //指定分块文件的信息
// ComposeSource composeSource = ComposeSource.builder().bucket("testbucket").object("chunk/" + i).build();
// sources.add(composeSource);
// }
List<ComposeSource> sources = Stream.iterate(0, i -> ++i).limit(6).map(i -> ComposeSource.builder().bucket("testbucket").object("chunk/" + i).build()).collect(Collectors.toList());
//指定合并后的objectName等信息
ComposeObjectArgs composeObjectArgs = ComposeObjectArgs.builder()
.bucket("testbucket")
.object("merge01.mp4")
.sources(sources)//指定源文件
.build();
//合并文件,
//报错size 1048576 must be greater than 5242880,minio默认的分块文件大小为5M
minioClient.composeObject(composeObjectArgs);
}
原文地址:https://blog.csdn.net/qq_69183322/article/details/139509885
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!