2023年9月15日18:26:10

master
zhangmeng 2023-09-15 18:26:19 +08:00
parent adc4040cc8
commit 17c4c219ac
4 changed files with 315 additions and 0 deletions

1
.gitignore vendored
View File

@ -37,3 +37,4 @@ build/
.vscode/
/logs/
/bin/

19
pom.xml
View File

@ -412,6 +412,25 @@
<artifactId>richtextfx</artifactId>
<version>0.10.0</version>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.4.3</version>
</dependency>
<!--根据扩展名取mimetype-->
<dependency>
<groupId>com.j256.simplemagic</groupId>
<artifactId>simplemagic</artifactId>
<version>1.17</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.8.1</version>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,30 @@
package com.zhangmeng.tools.controller;
import com.zhangmeng.tools.utils.MinioUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import static com.zhangmeng.tools.utils.MinioUtils.test;
/**
*
*
* @author zhangmeng
* @version 1.0
* @date 202391515:19:58
*/
@Slf4j
public class BigFileUploadController {
}

View File

@ -0,0 +1,265 @@
package com.zhangmeng.tools.utils;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.UploadObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
@Slf4j
public class MinioUtils {
public static void getInstance(String endpoint, String accessKey, String secretKey) {
minioClient(endpoint, accessKey, secretKey);
}
public static class FileChunkReader implements AutoCloseable {
private final FileChannel channel;
private final ByteBuffer buffer;
private long chunkCount;
private final int CHUNK_SIZE;
private String name;
private File file;
private String extension;
private String md5;
public FileChunkReader(Path filePath, int chunkSize) throws IOException {
this.channel = FileChannel.open(filePath, StandardOpenOption.READ);
this.buffer = ByteBuffer.allocate(chunkSize);
this.CHUNK_SIZE = chunkSize;
long totalSize = channel.size(); // total size of the file in bytes
this.chunkCount = (totalSize + CHUNK_SIZE - 1) / CHUNK_SIZE;
this.file = filePath.toFile();
this.name = this.file.getName();
extension();//拓展名
md5();
}
public void md5() throws IOException {
this.md5 = DigestUtils.md5Hex(new FileInputStream(this.file));
}
public void extension() {
this.extension = FilenameUtils.getExtension(file.getName());
}
public byte[] readNextChunk() throws IOException {
buffer.clear();
int bytesRead = channel.read(buffer);
if (bytesRead == -1) { // 文件结束
return null;
}
buffer.flip(); // 准备从缓冲区读取数据
byte[] chunk = new byte[bytesRead];
buffer.get(chunk);
return chunk;
}
public String getExtension() {
return extension;
}
public void setExtension(String extension) {
this.extension = extension;
}
public String getMd5() {
return md5;
}
public void setMd5(String md5) {
this.md5 = md5;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public FileChannel getChannel() {
return channel;
}
public ByteBuffer getBuffer() {
return buffer;
}
public long getChunkCount() {
return chunkCount;
}
public void setChunkCount(long chunkCount) {
this.chunkCount = chunkCount;
}
public int getCHUNK_SIZE() {
return CHUNK_SIZE;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public void close() throws IOException {
channel.close();
}
}
private static MinioClient minioClient;
public static MinioClient getMinioClient() {
return minioClient;
}
private static void minioClient(String endpoint, String accessKey, String secretKey) {
minioClient = MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
}
public static void addMediaFilesToMinIO(byte[] bytes, String bucket, String objectName, String contentType) {
//转为流
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
try {
PutObjectArgs putObjectArgs = PutObjectArgs.builder().bucket(bucket).object(objectName)
//-1表示文件分片按5M(不小于5M,不大于5T),分片数量最大10000
.stream(byteArrayInputStream, byteArrayInputStream.available(), -1)
.contentType(contentType)
.build();
minioClient.putObject(putObjectArgs);
} catch (Exception e) {
e.printStackTrace();
}
}
//将文件上传到minIO传入文件绝对路径
public static void addMediaFilesToMinIO(String filePath, String bucket, String objectName) {
try {
minioClient.uploadObject(
UploadObjectArgs.builder()
.bucket(bucket)
.object(objectName)
.filename(filePath)
.build());
} catch (Exception e) {
e.printStackTrace();
log.error("上传文件到文件系统出错");
}
}
public static File downloadFileFromMinIO(File file, String bucket, String objectName) {
InputStream fileInputStream = null;
OutputStream fileOutputStream = null;
try {
fileInputStream = minioClient.getObject(
GetObjectArgs.builder()
.bucket(bucket)
.object(objectName)
.build());
try {
fileOutputStream = new FileOutputStream(file);
IOUtils.copy(fileInputStream, fileOutputStream);
} catch (IOException e) {
log.error("下载文件" + objectName + "出错");
}
} catch (Exception e) {
e.printStackTrace();
log.error("文件不存在" + objectName);
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return file;
}
//得到分块文件的目录
public static String getChunkFileFolderPath(String fileMd5) {
return fileMd5.substring(0, 1) + "/" + fileMd5.substring(1, 2) + "/" + fileMd5 + "/" + "chunk" + "/";
}
public static final int chunkSize = 1024 * 1024 * 2;
public static void test(String path){
try (MinioUtils.FileChunkReader reader = new MinioUtils.FileChunkReader(Path.of(path), chunkSize);) { // 1MB chunk size
byte[] chunk;
//扩展名
String extName = reader.getExtension();
//合并为一个文件
//创建临时文件作为合并文件
File mergeFile = null;
try {
mergeFile = File.createTempFile(reader.getMd5(), "." + extName);
} catch (IOException e) {
e.printStackTrace();
log.error("合并文件过程中创建临时文件出错");
}
byte[] b = new byte[1024 * 1024];
RandomAccessFile raf_write = new RandomAccessFile(mergeFile, "rw");
while ((chunk = reader.readNextChunk()) != null) {
// process the chunk
String md5Hex = DigestUtils.md5Hex(chunk);
System.out.println("--------------" + md5Hex);
System.out.println("--------------" + reader.getChunkCount());
//开始合并
InputStream inputStream = new ByteArrayInputStream(chunk);
int len = -1;
while ((len = inputStream.read(b)) != -1) {
//向合并后的文件写
raf_write.write(b, 0, len);
}
}
System.out.println(mergeFile);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
test("G:\\FXGL基础入门教程 Java游戏引擎教程_1简介与游戏演示\\1-1 简介与游戏演示-1080P 高清-AVC.mp4");
}
}