|
|
@@ -0,0 +1,155 @@
|
|
|
+package cn.reghao.devops.manager.account.service;
|
|
|
+
|
|
|
+import cn.reghao.devops.manager.account.db.repository.DiskFileRepository;
|
|
|
+import cn.reghao.devops.manager.account.model.po.DiskFile;
|
|
|
+import cn.reghao.jutil.jdk.security.DigestUtil;
|
|
|
+import cn.reghao.jutil.web.ServletUtil;
|
|
|
+import org.apache.commons.io.FileUtils;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+
|
|
|
+import javax.annotation.PostConstruct;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.io.*;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Path;
|
|
|
+import java.nio.file.StandardCopyOption;
|
|
|
+import java.util.List;
|
|
|
+import java.util.UUID;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author reghao
|
|
|
+ * @date 2024-01-19 21:29:24
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class FileService {
|
|
|
+ // 1MiB
|
|
|
+ private final int bufSize = 1024*1024;
|
|
|
+ private final String storeDir = "";
|
|
|
+ private final DiskFileRepository diskFileRepository;
|
|
|
+
|
|
|
+ public FileService(DiskFileRepository diskFileRepository) {
|
|
|
+ this.diskFileRepository = diskFileRepository;
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostConstruct
|
|
|
+ public void initLocalStore() throws IOException {
|
|
|
+ File dir1 = new File(storeDir);
|
|
|
+ if (!dir1.exists()) {
|
|
|
+ //FileUtils.forceMkdir(dir1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void getFile(String objectName) throws IOException {
|
|
|
+ DiskFile diskFile = diskFileRepository.findByObjectName(objectName);
|
|
|
+ if (diskFile == null) {
|
|
|
+ writeResponse(HttpServletResponse.SC_NOT_FOUND);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ String absolutePath = diskFile.getAbsolutePath();
|
|
|
+ String contentType = diskFile.getContentType();
|
|
|
+ long size = diskFile.getSize();
|
|
|
+ HttpServletResponse response = ServletUtil.getResponse();
|
|
|
+ response.setStatus(HttpServletResponse.SC_OK);
|
|
|
+ response.setContentType(contentType);
|
|
|
+ response.setContentLengthLong(size);
|
|
|
+
|
|
|
+ OutputStream outputStream = response.getOutputStream();
|
|
|
+ writeResponse(outputStream, absolutePath, 0, size);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void writeResponse(int statusCode) throws IOException {
|
|
|
+ HttpServletResponse response = ServletUtil.getResponse();
|
|
|
+ response.setStatus(statusCode);
|
|
|
+ OutputStream outputStream = response.getOutputStream();
|
|
|
+ outputStream.flush();
|
|
|
+ outputStream.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void writeResponse(OutputStream outputStream, String absolutePath, long start, long end) throws IOException {
|
|
|
+ RandomAccessFile raf = new RandomAccessFile(absolutePath, "r");
|
|
|
+ raf.seek(start);
|
|
|
+
|
|
|
+ long len = end-start+1;
|
|
|
+ if (len < bufSize) {
|
|
|
+ int len1 = (int) len;
|
|
|
+ byte[] buf1 = new byte[len1];
|
|
|
+ int readLen1 = raf.read(buf1, 0, len1);
|
|
|
+ outputStream.write(buf1, 0, readLen1);
|
|
|
+ } else {
|
|
|
+ byte[] buf = new byte[bufSize];
|
|
|
+ long totalRead = 0;
|
|
|
+ int readLen;
|
|
|
+ while ((readLen = raf.read(buf, 0, bufSize)) != -1) {
|
|
|
+ outputStream.write(buf, 0, readLen);
|
|
|
+ totalRead += readLen;
|
|
|
+
|
|
|
+ long left = len - totalRead;
|
|
|
+ if (left < bufSize) {
|
|
|
+ int left1 = (int) left;
|
|
|
+ byte[] buf1 = new byte[left1];
|
|
|
+ int readLen1 = raf.read(buf1, 0, left1);
|
|
|
+ outputStream.write(buf1, 0, readLen1);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ outputStream.flush();
|
|
|
+ outputStream.close();
|
|
|
+ raf.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ public String putFile(MultipartFile file) throws Exception {
|
|
|
+ long size = file.getSize();
|
|
|
+ String filename = file.getOriginalFilename();
|
|
|
+ String suffix = getSuffix(filename);
|
|
|
+
|
|
|
+ String objectId = UUID.randomUUID().toString().replace("-", "");;
|
|
|
+ String objectName;
|
|
|
+ if (suffix.isBlank()) {
|
|
|
+ objectName = String.format("file/%s", objectId);
|
|
|
+ } else {
|
|
|
+ objectName = String.format("file/%s%s", objectId, suffix);
|
|
|
+ }
|
|
|
+
|
|
|
+ String contentId = UUID.randomUUID().toString().replace("-", "");
|
|
|
+ File savedFile = saveFile(file.getInputStream(), contentId, suffix);
|
|
|
+ String contentType = Files.probeContentType(Path.of(savedFile.getAbsolutePath()));
|
|
|
+ String sha256sum = DigestUtil.sha256sum(savedFile.getAbsolutePath());
|
|
|
+
|
|
|
+ List<DiskFile> diskFiles = diskFileRepository.findBySha256sum(sha256sum);
|
|
|
+ DiskFile diskFile;
|
|
|
+ if (!diskFiles.isEmpty()) {
|
|
|
+ DiskFile existFile = diskFiles.get(0);
|
|
|
+ diskFile = new DiskFile(objectName, objectId, existFile, filename);
|
|
|
+ FileUtils.deleteQuietly(savedFile);
|
|
|
+ } else {
|
|
|
+ diskFile = new DiskFile(objectName, objectId, savedFile.getAbsolutePath(), sha256sum, filename, contentType, size);
|
|
|
+ }
|
|
|
+
|
|
|
+ diskFileRepository.save(diskFile);
|
|
|
+ return "/" + objectName;
|
|
|
+ }
|
|
|
+
|
|
|
+ private File saveFile(InputStream inputStream, String contentId, String suffix) throws IOException {
|
|
|
+ String absolutePath = String.format("%s/%s%s", storeDir, contentId, suffix);
|
|
|
+ File file = new File(absolutePath);
|
|
|
+ if (file.exists()) {
|
|
|
+ throw new IOException(absolutePath + " exist");
|
|
|
+ }
|
|
|
+
|
|
|
+ Files.copy(inputStream, Path.of(absolutePath), StandardCopyOption.REPLACE_EXISTING);
|
|
|
+ return file;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getSuffix(String filename) {
|
|
|
+ if (filename == null) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ int idx = filename.lastIndexOf(".");
|
|
|
+ return idx == -1 ? "" : filename.substring(idx);
|
|
|
+ }
|
|
|
+}
|