MinIO學(xué)習(xí)指南看這一篇就夠了
一.前言
對(duì)象存儲(chǔ)是一種數(shù)據(jù)存儲(chǔ)架構(gòu)
,設(shè)計(jì)用于管理和處理大量非結(jié)構(gòu)化數(shù)據(jù)。與傳統(tǒng)的文件存儲(chǔ)和塊存儲(chǔ)不同,對(duì)象存儲(chǔ)通過將數(shù)據(jù)分解為離散的、獨(dú)立的單元或“對(duì)象”來存儲(chǔ)每個(gè)對(duì)象包含數(shù)據(jù)本身、相關(guān)的元數(shù)據(jù)和一個(gè)唯一的標(biāo)識(shí)符。
官網(wǎng):https://www.minio.org.cn
以下是對(duì)象存儲(chǔ)、服務(wù)器磁盤和分布式文件系統(tǒng)的對(duì)比表格:
特性 | 對(duì)象存儲(chǔ) | 服務(wù)器磁盤 | 分布式文件系統(tǒng) |
---|---|---|---|
存儲(chǔ)方式 | 以對(duì)象為基本單位存儲(chǔ)數(shù)據(jù),每個(gè)對(duì)象包含數(shù)據(jù)、元數(shù)據(jù)和唯一標(biāo)識(shí)符 | 數(shù)據(jù)直接存儲(chǔ)在服務(wù)器的本地磁盤上 | 數(shù)據(jù)分布在多個(gè)服務(wù)器節(jié)點(diǎn)上,通過網(wǎng)絡(luò)進(jìn)行數(shù)據(jù)訪問 |
優(yōu)點(diǎn) | 高可擴(kuò)展性: 能夠輕松擴(kuò)展至數(shù)十乃至數(shù)百EB的容量。 高效性: 扁平化結(jié)構(gòu),不受復(fù)雜目錄系統(tǒng)對(duì)性能的影響。 安全性高: 通常憑借HTTP調(diào)用對(duì)象存儲(chǔ)本身提供的認(rèn)證密鑰來提供數(shù)據(jù)訪問。 訪問方便: 支持HTTP(S)協(xié)議,采用REST的API方式調(diào)用和檢索數(shù)據(jù)。 成本相對(duì)低: 與塊存儲(chǔ)方式相比,對(duì)象存儲(chǔ)是最具成本效益的數(shù)據(jù)存儲(chǔ)類型。 | 開發(fā)便捷: 直接使用服務(wù)器磁盤,無需復(fù)雜的配置和開發(fā)工作。 成本低: 如果已有服務(wù)器和磁盤,不需要額外支付存儲(chǔ)服務(wù)費(fèi)用。 | 容易實(shí)現(xiàn)擴(kuò)容: 可以通過增加更多的服務(wù)器節(jié)點(diǎn)來擴(kuò)展存儲(chǔ)容量,實(shí)現(xiàn)水平擴(kuò)展。 |
缺點(diǎn) | 最終一致性 :由于不同節(jié)點(diǎn)的位置不同,數(shù)據(jù)同步時(shí)可能會(huì)有一定時(shí)間的延遲或者錯(cuò)誤。 不適合頻繁變動(dòng)的數(shù)據(jù) :對(duì)象存儲(chǔ)比較適合存儲(chǔ)那些變動(dòng)不大甚至不變的文件。 | 擴(kuò)展困難: 服務(wù)器磁盤的容量有限,當(dāng)存儲(chǔ)空間不足時(shí),擴(kuò)展磁盤容量可能需要更換更大容量的硬盤或者增加額外的磁盤陣列,成本較高且操作復(fù)雜。 | 復(fù)雜度高: 分布式文件系統(tǒng)的部署和維護(hù)相對(duì)復(fù)雜,需要專業(yè)的運(yùn)維團(tuán)隊(duì)來管理。 |
分布式文件系統(tǒng)
分布式文件系統(tǒng)(Distributed File System, DFS)是一種文件系統(tǒng),它使文件可以跨越多個(gè)服務(wù)器或存儲(chǔ)設(shè)備存儲(chǔ)和訪問。DFS 通過網(wǎng)絡(luò)將多個(gè)存儲(chǔ)資源組合成一個(gè)統(tǒng)一的文件系統(tǒng),使用戶和應(yīng)用程序可以像訪問本地文件一樣透明地訪問遠(yuǎn)程文件。
分布式文件系統(tǒng)的關(guān)鍵特性:
- 透明性:用戶和應(yīng)用程序可以像訪問本地文件一樣訪問遠(yuǎn)程文件,感受不到底層的復(fù)雜性。
- 高可用性:通過復(fù)制和冗余機(jī)制,確保即使某些節(jié)點(diǎn)或硬件發(fā)生故障,數(shù)據(jù)仍然可用。
- 可擴(kuò)展性:能夠處理隨著數(shù)據(jù)量和用戶數(shù)增加而增長(zhǎng)的需求。
- 容錯(cuò)性:通過數(shù)據(jù)冗余和錯(cuò)誤檢測(cè)機(jī)制,保證系統(tǒng)能繼續(xù)運(yùn)行,即使發(fā)生部分硬件或網(wǎng)絡(luò)故障。
- 性能:通過分布式架構(gòu),能夠有效地處理大量并發(fā)訪問請(qǐng)求。
MINIO
MinIO 是一個(gè)高性能、輕量級(jí)
的對(duì)象存儲(chǔ)服務(wù)器
,專為大規(guī)模數(shù)據(jù)存儲(chǔ)和分析而設(shè)計(jì)。它兼容 Amazon S3 API
,可以無縫替代 Amazon S3 作為存儲(chǔ)后端,并且支持在各種環(huán)境中部署,包括物理服務(wù)器、虛擬機(jī)、容器等。
FastDFS和MINIO的區(qū)別
以下是MinIO和FastDFS的對(duì)比表格:
特性 | MinIO | FastDFS |
---|---|---|
存儲(chǔ)類型 | 對(duì)象存儲(chǔ) | 文件存儲(chǔ) |
架構(gòu) | 單一守護(hù)進(jìn)程,支持分布式 | Tracker-Storage 分離 |
協(xié)議支持 | S3 兼容,支持 HTTP/REST API | 專有協(xié)議 |
數(shù)據(jù)冗余 | 糾刪碼,多節(jié)點(diǎn)和磁盤故障容錯(cuò) | 主從復(fù)制,多副本 |
性能 | 高性能,適合大文件和海量數(shù)據(jù)存儲(chǔ) | 適合小文件存儲(chǔ),上傳/下載性能較高 |
擴(kuò)展性 | 高度可擴(kuò)展,支持水平擴(kuò)展 | 可擴(kuò)展但管理復(fù)雜 |
管理工具 | Web 界面,支持 Prometheus 監(jiān)控 | 命令行工具 |
生態(tài)系統(tǒng) | 廣泛,集成度高 | 生態(tài)相對(duì)較小,集成度低 |
安裝部署 | 簡(jiǎn)單,開箱即用 | 復(fù)雜,需要專業(yè)知識(shí) |
社區(qū)與支持 | 活躍,有官方文檔和社區(qū)支持 | 缺乏官方文檔和持續(xù)更新 |
MinIO和FastDFS各有優(yōu)勢(shì),MinIO在兼容性、擴(kuò)展性、性能和生態(tài)系統(tǒng)方面表現(xiàn)更佳,適合云原生應(yīng)用、大數(shù)據(jù)分析等場(chǎng)景;而FastDFS在處理小文件方面性能出色,適合需要海量小文件存儲(chǔ)的場(chǎng)景。具體選擇可以根據(jù)實(shí)際需求和使用場(chǎng)景來決定。
二.Windows環(huán)境安裝Minio
1、下載服務(wù)端和客戶端安裝包文件
下載地址:MinIO | Code and downloads to create high performance object storage
服務(wù)端文件:minio.exe 用于接收文件信息
客戶端文件:mac.exe 用于上傳文件 ,如果用程序代碼操作文件存儲(chǔ),只啟動(dòng)服務(wù)端就ok
2、啟動(dòng)minio服務(wù)器
特別提示:在windows 安裝軟件我們都習(xí)慣雙擊.exe 文件啟動(dòng)。minio可不行奧,可不行,可不行。千萬不能去雙擊運(yùn)行,這樣可能會(huì)導(dǎo)致最終啟動(dòng)失??;無論是windows還是linux都建議通過命令啟動(dòng)的。
以管理員權(quán)限打開cmd窗口,進(jìn)入到minio.exe所在bin目錄
2.2、設(shè)置用戶名
用于登錄minio客戶端
setx MINIO_ROOT_USER name
設(shè)置登錄密碼
setx MINIO_ROOT_PASSWORD password
2.3、啟動(dòng)Minio服務(wù)
.\minio.exe server D:\develpo\minio\data --console-address "127.0.0.1:9000" --address "127.0.0.1:9005"
D:\develpo\minio\data 指定數(shù)據(jù)存放路徑
9005是控制臺(tái)端口,9000是服務(wù)的端口。
4.5、訪問minio服務(wù)器
訪問客戶端地址 http://127.0.0.1:9000/ 輸入用戶密碼
使用 Docker 安裝
docker run -p 9000:9000 minio/minio server /data
三. 基本概念
基本概念
概念 | 定義 | 特點(diǎn) |
---|---|---|
Object | 存儲(chǔ)到MinIO的基本對(duì)象,如文件、字節(jié)流等 | 具有唯一標(biāo)識(shí),可設(shè)置元數(shù)據(jù) |
Bucket | 用來存儲(chǔ)Object的邏輯空間,相當(dāng)于頂層文件夾 | 數(shù)據(jù)隔離,命名唯一,可設(shè)置權(quán)限 |
Drive | 存儲(chǔ)數(shù)據(jù)的磁盤,啟動(dòng)時(shí)以參數(shù)傳入 | 是數(shù)據(jù)存儲(chǔ)載體,容量有限 |
Set | 一組Drive的集合 | 分布式部署自動(dòng)劃分,對(duì)象存儲(chǔ)于其上,Drive數(shù)量固定,盡可能分布在不同節(jié)點(diǎn) |
MinIO 糾刪碼 EC (Erasure Code)
糾刪碼(Erasure Code, EC) 是一種數(shù)據(jù)保護(hù)方法,它將數(shù)據(jù)分割成片段,生成冗余數(shù)據(jù)塊,并將這些數(shù)據(jù)塊存儲(chǔ)在不同的位置,如磁盤、存儲(chǔ)節(jié)點(diǎn)或其他地理位置。MinIO 采用 Reed-Solomon 糾刪碼實(shí)現(xiàn),將對(duì)象拆分成數(shù)據(jù)塊和奇偶校驗(yàn)塊,以提高數(shù)據(jù)的冗余性和可用性。
簡(jiǎn)單來說就是可以通過數(shù)學(xué)計(jì)算,把丟失的數(shù)據(jù)進(jìn)行還原,它可以將n份原始數(shù)據(jù),增加m份數(shù)據(jù),并能通過n+m份中的任意n份數(shù)據(jù),還原為原始數(shù)據(jù)。
即如果有任意小于等于m份的數(shù)據(jù)失效,仍然能通過剩下的數(shù)據(jù)還原出來。
舉個(gè)最簡(jiǎn)單例子就是有兩個(gè)數(shù)據(jù)(d1, d2),用一個(gè)校驗(yàn)和y(d1 + d2 = y)即可保證即使丟失其中一個(gè),依然可以還原數(shù)據(jù)。如丟失 d1 ,則使用 y - d2 = d1 還原,同理,d2 丟失或者y丟失,均可通過計(jì)算得出。
存儲(chǔ)形式
當(dāng)文件對(duì)象上傳到MinIO時(shí),數(shù)據(jù)會(huì)以特定的形式存儲(chǔ)在對(duì)應(yīng)的數(shù)據(jù)存儲(chǔ)磁盤中。具體存儲(chǔ)形式如下:
目錄結(jié)構(gòu):
- 以Bucket名稱為目錄。
- 文件名稱為下一級(jí)目錄。
- 文件名下包含編碼數(shù)據(jù)塊及檢驗(yàn)塊(EC碼)和元數(shù)據(jù)文件(xl.meta)。
數(shù)據(jù)塊和元數(shù)據(jù)文件:
- 編碼數(shù)據(jù)塊及檢驗(yàn)塊(EC碼):這些塊存儲(chǔ)在奇數(shù)編號(hào)的磁盤上,例如data01和data03。
- 元數(shù)據(jù)文件(xl.meta):這些文件存儲(chǔ)在偶數(shù)編號(hào)的磁盤上,例如data02和data04。
例如,假設(shè)我們有四塊磁盤:data01、data02、data03、data04。存儲(chǔ)形式如下:
data01:
/bucket_name/file_name/part.1
(編碼數(shù)據(jù)塊)/bucket_name/file_name/part.2
(編碼數(shù)據(jù)塊)- …
data02:
/bucket_name/file_name/xl.meta
(元數(shù)據(jù)文件)
data03:
/bucket_name/file_name/part.3
(編碼數(shù)據(jù)塊)/bucket_name/file_name/part.4
(編碼數(shù)據(jù)塊)…
data04:
/bucket_name/file_name/xl.meta
(元數(shù)據(jù)文件)
這種存儲(chǔ)形式確保了數(shù)據(jù)的冗余和高可用性,通過糾刪碼技術(shù),即使部分磁盤損壞,數(shù)據(jù)仍然可以被恢復(fù)。
Minio中的存儲(chǔ)級(jí)別
Minio當(dāng)前支持兩種存儲(chǔ)級(jí)別:Reduced Redundancy
和Standard
,通過對(duì)兩種級(jí)別的設(shè)置來修改對(duì)象的Parity Drives
( P)(奇偶校驗(yàn)塊)和Data Drives
(D)(數(shù)據(jù)塊)的比例,讓用戶能夠更好的控制磁盤使用率和容錯(cuò)性。
STANDARD
STANDARD
存儲(chǔ)級(jí)別包含比REDUCED_REDUNDANCY
存儲(chǔ)級(jí)別更多的奇偶校驗(yàn)塊,因此STANDARD
存儲(chǔ)級(jí)別的奇偶校驗(yàn)塊需要滿足如下條件:
- 在未設(shè)置
REDUCED_REDUNDANCY
存儲(chǔ)級(jí)別的情況下,STANDARD
存儲(chǔ)級(jí)別的奇偶校驗(yàn)塊需要大于等于2; - 在設(shè)置了
REDUCED_REDUNDANCY
存儲(chǔ)級(jí)別的情況下,STANDARD
存儲(chǔ)級(jí)別的奇偶校驗(yàn)塊需要大于REDUCED_REDUNDANCY
存儲(chǔ)級(jí)別的奇偶校驗(yàn)塊數(shù)量 - 奇偶校驗(yàn)塊的數(shù)量必須小于數(shù)據(jù)塊,所以
STANDARD
存儲(chǔ)級(jí)別的奇偶校驗(yàn)塊不能大于N/2(N為Erasure Set中的磁盤數(shù)量)
STANDARD
存儲(chǔ)級(jí)別的奇偶校驗(yàn)塊的默認(rèn)值取決于Erasure Set
中的磁盤數(shù)量:
Erasure Set Size | Default Parity (EC:N) |
---|---|
5 or fewer | EC:2 |
6-7 | EC:3 |
8 or more | EC:4 |
REDUCED_REDUNDANCY
存儲(chǔ)級(jí)別包含比STANDARD
存儲(chǔ)級(jí)別更少的奇偶校驗(yàn)塊,因此REDUCED_REDUNDANCY存儲(chǔ)級(jí)別的奇偶校驗(yàn)塊需要滿足如下條件:
- 在未設(shè)置
STANDARD
存儲(chǔ)級(jí)別的情況下,REDUCED_REDUNDANCY
存儲(chǔ)級(jí)別的奇偶校驗(yàn)塊需要小于N/2 - 在設(shè)置了
STANDARD
存儲(chǔ)級(jí)別的情況下,REDUCED_REDUNDANCY
存儲(chǔ)級(jí)別的奇偶校驗(yàn)塊需要小于STANDARD存儲(chǔ)級(jí)別的奇偶校驗(yàn)塊數(shù)量 - 奇偶校驗(yàn)塊的數(shù)量必須小于數(shù)據(jù)塊,且
REDUCED_REDUNDANCY
存儲(chǔ)級(jí)別的奇偶校驗(yàn)塊需要小于STANDARD
存儲(chǔ)級(jí)別的奇偶校驗(yàn)塊數(shù)量,那么REDUCED_REDUNDANCY
存儲(chǔ)級(jí)別的奇偶校驗(yàn)塊需要大于等于2,所以Erasure Set
中的磁盤數(shù)量大于4的時(shí)候才支持REDUCED_REDUNDANCY
存儲(chǔ)級(jí)別。
REDUCED_REDUNDANCY
存儲(chǔ)級(jí)別的奇偶校驗(yàn)塊默認(rèn)值為:EC:2
使用
配置存儲(chǔ)級(jí)別
有以下兩種配置方式:
環(huán)境變量
export MINIO_STORAGE_CLASS_STANDARD=EC:4 export MINIO_STORAGE_CLASS_RRS=EC:2
設(shè)置以上環(huán)境變量并重啟服務(wù)
mc admin
mc admin config set myminio/ storage_class standard="EC:4" mc admin config set myminio/ storage_class rrs="EC:2" # 重啟minio服務(wù) mc admin service restart myminio/
存儲(chǔ)方案
四. 命令操作
列出存儲(chǔ)桶
mc ls <alias>
這會(huì)列出指定 MinIO 服務(wù)器上的所有存儲(chǔ)桶。
創(chuàng)建存儲(chǔ)桶
mc mb <alias>/<bucket_name>
這會(huì)在指定 MinIO 服務(wù)器上創(chuàng)建一個(gè)新的存儲(chǔ)桶。
上傳文件
mc cp <file_path> <alias>/<bucket_name>
這會(huì)將本地文件上傳到指定的 MinIO 存儲(chǔ)桶中。
下載文件
mc cp <alias>/<bucket_name>/<file_name> <local_file_path>
這會(huì)將 MinIO 存儲(chǔ)桶中的文件下載到本地。
復(fù)制對(duì)象
mc cp <source> <target>
這會(huì)復(fù)制對(duì)象從一個(gè)位置到另一個(gè)位置,可以是存儲(chǔ)桶內(nèi)的對(duì)象或不同存儲(chǔ)桶間的對(duì)象。
移動(dòng)對(duì)象
mc mv <source> <target>
這會(huì)移動(dòng)對(duì)象從一個(gè)位置到另一個(gè)位置,與復(fù)制不同的是,移動(dòng)后源位置的對(duì)象將被刪除。
刪除對(duì)象
mc rm <alias>/<bucket_name>/<object_name>
這會(huì)刪除指定的對(duì)象。
刪除存儲(chǔ)桶
mc rb <alias>/<bucket_name>
這會(huì)刪除指定的存儲(chǔ)桶及其中的所有對(duì)象。
五 . MinIO 整合 SpringBoot
1、導(dǎo)入依賴:
<dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.2.2</version> </dependency>
2、在SpringBoot的配置文件中編寫 MinIO 的配置:
minio: config: url: http://127.0.0.1:9005 #ip地址 accessKey: admin # 賬號(hào) secretKey: admin962464 # 密碼 secure: false #如果是true,則用的是https而不是http,默認(rèn)值是true bucketName: "test" # 桶的名字 相當(dāng)于文件夾
3、編寫 MinIO 配置類:
import io.minio.MinioClient; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Data @Configuration @ConfigurationProperties(prefix = "minio.config") public class MinioConfig { /** * 服務(wù)地址 */ private String url; /** * 用戶名 */ private String accessKey; /** * 密碼 */ private String secretKey; /** * 存儲(chǔ)桶名稱 */ private String bucketName; @Bean public MinioClient getMinioClient() { return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build(); } }
4、編寫 MinIO 的工具類:
import com.jjy.shopping_file_service.config.MinioConfig; import io.minio.*; import io.minio.http.Method; import io.minio.messages.Bucket; import io.minio.messages.Item; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.util.FastByteArrayOutputStream; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.UUID; @Slf4j @Component public class MinIOUtil { @Resource private MinioConfig minioConfig; @Resource private MinioClient minioClient; /** * 查看存儲(chǔ)bucket是否存在 * * @param bucketName 存儲(chǔ)桶名稱 * @return boolean */ public Boolean bucketExists(String bucketName) { Boolean found; try { found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); } catch (Exception e) { e.printStackTrace(); return false; } return found; } /** * 創(chuàng)建存儲(chǔ)bucket * * @param bucketName 存儲(chǔ)桶名稱 * @return Boolean */ public Boolean makeBucket(String bucketName) { try { minioClient.makeBucket(MakeBucketArgs.builder() .bucket(bucketName) .build()); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * 刪除存儲(chǔ)bucket * * @param bucketName 存儲(chǔ)桶名稱 * @return Boolean */ public Boolean removeBucket(String bucketName) { try { minioClient.removeBucket(RemoveBucketArgs.builder() .bucket(bucketName) .build()); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * 獲取全部bucket * * @return 存儲(chǔ)桶列表 */ public List<Bucket> getAllBuckets() { try { return minioClient.listBuckets(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 文件上傳 * * @param file 文件 * @return 文件對(duì)象名稱 */ public String upload(MultipartFile file) { String originalFilename = file.getOriginalFilename(); System.out.println(originalFilename); if (!StringUtils.hasText(originalFilename)) { throw new RuntimeException(); } String fileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf(".")); String prefix = new SimpleDateFormat("yyyy/MM/dd").format(new Date()); String objectName = prefix + "/" + fileName; try { PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(minioConfig.getBucketName()).object(objectName) .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build(); // 文件名稱相同會(huì)覆蓋 minioClient.putObject(objectArgs); } catch (Exception e) { e.printStackTrace(); return null; } return objectName; } /** * 預(yù)覽圖片 * * @param fileName 文件名稱 * @return 文件預(yù)覽鏈接 */ public String preview(String fileName) { // 查看文件地址 GetPresignedObjectUrlArgs build = GetPresignedObjectUrlArgs .builder() .bucket(minioConfig.getBucketName()) .object(fileName).method(Method.GET).build(); try { String url = minioClient.getPresignedObjectUrl(build); return url; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 文件下載 * * @param fileName 文件名稱 * @param res response */ public void download(String fileName, HttpServletResponse res) { GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(minioConfig.getBucketName()) .object(fileName).build(); try (GetObjectResponse response = minioClient.getObject(objectArgs)) { byte[] buf = new byte[1024]; int len; try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) { while ((len = response.read(buf)) != -1) { os.write(buf, 0, len); } os.flush(); byte[] bytes = os.toByteArray(); res.setCharacterEncoding("utf-8"); res.addHeader("Content-Disposition", "attachment;fileName=" + fileName); try (ServletOutputStream stream = res.getOutputStream()) { stream.write(bytes); stream.flush(); } } } catch (Exception e) { e.printStackTrace(); } } /** * 查看文件對(duì)象 * * @return 存儲(chǔ)bucket內(nèi)文件對(duì)象信息 */ public List<Item> listObjects() { Iterable<Result<Item>> results = minioClient.listObjects( ListObjectsArgs.builder().bucket(minioConfig.getBucketName()).build()); List<Item> items = new ArrayList<>(); try { for (Result<Item> result : results) { items.add(result.get()); } } catch (Exception e) { e.printStackTrace(); return null; } return items; } /** * 刪除 * * @param fileName 文件名稱 * @return 是否刪除成功 */ public boolean remove(String fileName) { try { minioClient.removeObject(RemoveObjectArgs.builder() .bucket(minioConfig.getBucketName()) .object(fileName) .build()); } catch (Exception e) { return false; } return true; } }
5、Controller:
import com.cyw.miniodemo.config.MinioConfig; import com.cyw.miniodemo.pojo.Rst; import com.cyw.miniodemo.service.FileUploadService; import com.cyw.miniodemo.utils.MinIOUtil; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; import java.util.Map; @Slf4j @RestController @RequestMapping("/api/file") @AllArgsConstructor public class FileUploadController { private MinioConfig minioConfig; private MinIOUtil minIOUtil; private FileUploadService fileUploadService; @GetMapping("/bucketExists") public Rst bucketExists(@RequestParam("bucketName") String bucketName) { Map<String, Object> map = new HashMap<>(); map.put("bucketExists", minIOUtil.bucketExists(bucketName)); return Rst.ok("查詢成功", map); } @GetMapping("/makeBucket") public Rst makeBucket(@RequestParam("bucketName") String bucketName) { Map<String, Object> map = new HashMap<>(); map.put("makeBucketSuccess", minIOUtil.makeBucket(bucketName)); return Rst.ok("創(chuàng)建成功", map); } @GetMapping("/removeBucket") public Rst removeBucket(@RequestParam("bucketName") String bucketName) { Map<String, Object> map = new HashMap<>(); map.put("deleteBucketSuccess", minIOUtil.removeBucket(bucketName)); return Rst.ok("刪除成功", map); } @GetMapping("/getAllBuckets") public Rst getAllBuckets() { Map<String, Object> map = new HashMap<>(); map.put("buckets", minIOUtil.getAllBuckets()); return Rst.ok("查詢成功", map); } @PostMapping("/upload") public Rst upload(@RequestParam("file") MultipartFile file) { String objectName = minIOUtil.upload(file); if (objectName != null) { Map<String, Object> map = new HashMap<>(); map.put("url", (minioConfig.getEndpoint() + "/" + minioConfig.getBucketName() + "/" + objectName)); return Rst.ok("上傳成功", map); } return Rst.fail("上傳失敗"); } @GetMapping("/preview") public Rst preview(@RequestParam("fileName") String fileName) { Map<String, Object> map = new HashMap<>(); map.put("url", minIOUtil.preview(fileName)); return Rst.ok("預(yù)覽成功", map); } @GetMapping("/download") public Rst download(@RequestParam("fileName") String fileName, HttpServletResponse resp) { minIOUtil.download(fileName, resp); return Rst.ok(); } @PostMapping("/delete") public Rst remove(@RequestBody Map<String, String> params) { String url = params.get("url"); String objName = url.substring(url.lastIndexOf(minioConfig.getBucketName() + "/") + minioConfig.getBucketName().length() + 1); log.info("刪除對(duì)象: {}", objName); minIOUtil.remove(objName); return Rst.ok("刪除成功"); } }
到此這篇關(guān)于MinIO學(xué)習(xí)指南看這一篇就夠了的文章就介紹到這了,更多相關(guān)MinIO命令內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringMVC通過攔截器實(shí)現(xiàn)IP黑名單
這篇文章主要為大家詳細(xì)介紹了SpringMVC通過攔截器實(shí)現(xiàn)IP黑名單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08Netty分布式NioSocketChannel注冊(cè)到selector方法解析
這篇文章主要為大家介紹了Netty分布式源碼分析NioSocketChannel注冊(cè)到selector方法的解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03使用Java的Lucene搜索工具對(duì)檢索結(jié)果進(jìn)行分組和分頁(yè)
這篇文章主要介紹了使用Java的搜索工具Lucene對(duì)檢索結(jié)果進(jìn)行分組和分頁(yè)的方法,Luence是Java環(huán)境中的一個(gè)全文檢索引擎工具包,需要的朋友可以參考下2016-03-03SpringBoot之ApplicationRunner解析(spring容器啟動(dòng)完成執(zhí)行的類)
這篇文章主要介紹了SpringBoot之ApplicationRunner解析(spring容器啟動(dòng)完成執(zhí)行的類),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05Mapper類中存在名稱相同的方法重載報(bào)錯(cuò)問題
這篇文章主要介紹了Mapper類中存在名稱相同的方法重載報(bào)錯(cuò)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03idea中將單個(gè)java類導(dǎo)出為jar包文件的方法
這篇文章主要給大家介紹了關(guān)于idea中將單個(gè)java類導(dǎo)出為jar包文件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09