minio設置端口 minio.exe server --address 127.0.0.1:9000 --console-address 127.0.0.1:9001 C:\minio\data
如果要創建目錄,直接在上傳文件時在路徑前加上目錄即可
public class MinioHelper
{
/// <summary>
///
/// </summary>
/// <param name="endPoint"></param>
/// <param name="accessKey"></param>
/// <param name="secretKey"></param>
/// <param name="withSSL"></param>
/// <returns></returns>
public static MinioClient Create(string endPoint, string accessKey, string secretKey, bool withSSL = false)
{
MinioClient client = new MinioClient()
.WithEndpoint(endPoint)
.WithCredentials(accessKey,
secretKey);
if (withSSL)
{
client = client.WithSSL();
}
return client.Build();
}
#region 操作存儲桶
/// <summary>
/// 創建存儲桶
///
/// <example >
/// <code >
/// MinioHelper.MakeBucket(minio, buckName).Wait();
/// </code>
///
/// </example>
/// </summary>
/// <param name = "minio" > 連接實例 </param >
/// <param name="bucketName">存儲桶名稱</param>
/// <param name = "loc" > 可選參數 </param >
/// <returns ></returns >
public static Task MakeBucket(MinioClient minio, string bucketName, string loc = "us-east-1")
{
try
{
bool found = BucketExists(minio, bucketName);
if (found)
{
throw new Exception(string.Format("存儲桶[{0}]已存在", bucketName));
}
MakeBucketArgs args = new MakeBucketArgs()
.WithBucket(bucketName)
.WithLocation(loc);
return minio.MakeBucketAsync(args);
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
/// <summary>
/// 校驗是否存在,如果不存在則報錯
/// <example>
/// 調用示例
/// <code>
/// bool exists = MinioHelper.BucketExists(minio, buckName);
/// </code>
/// </example>
/// </summary>
/// <param name="minio"></param>
/// <param name="bucketName"></param>
/// <exception cref="Exception"></exception>
private static void CheckBucket(MinioClient minio, string bucketName)
{
bool found = BucketExists(minio, bucketName);
if (!found)
{
throw new Exception(string.Format("存儲桶[{0}]不存在", bucketName));
}
}
/// <summary>
/// 列出所有的存儲桶
/// </summary>
/// <example>
/// <code>
/// abc</code>
/// </example>
/// <param name="minio">連接實例</param>
/// <returns></returns>
public static ListAllMyBucketsResult ListBuckets(MinioClient minio)
{
Task<ListAllMyBucketsResult> data = minio.ListBucketsAsync();
data.Wait();
return data.Result;
}
/// <summary>
/// 檢查存儲桶是否存在
/// </summary>
/// <example>
/// <code>
/// var data = MinioHelper.ListBuckets(minio);
/// </code>
/// </example>
/// <param name="minio">連接實例</param>
/// <param name="bucketName">存儲桶名稱</param>
/// <returns></returns>
public static bool BucketExists(MinioClient minio, string bucketName, CancellationToken cancellationToken = default(CancellationToken))
{
try
{
BucketExistsArgs args = new BucketExistsArgs()
.WithBucket(bucketName);
Task<bool> bucketExistTask = minio.BucketExistsAsync(args);
Task.WaitAll(bucketExistTask);
return bucketExistTask.Result;
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
/// <summary>
/// 刪除一個存儲桶
/// </summary>
/// <param name="minio">連接實例</param>
/// <param name="bucketName">存儲桶名稱</param>
/// <returns></returns>
public static Task RemoveBucket(MinioClient minio, string bucketName, CancellationToken cancellationToken = default(CancellationToken))
{
try
{
CheckBucket(minio, bucketName);
RemoveBucketArgs args = new RemoveBucketArgs()
.WithBucket(bucketName);
return minio.RemoveBucketAsync(args, cancellationToken);
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
/// <summary>列出存儲桶里的對象
/// 列出存儲桶里的對象
/// </summary>
/// <param name="minio">連接實例</param>
/// <param name="bucketName">存儲桶名稱</param>
/// <param name="prefix">對象的前綴</param>
/// <param name="recursive">true代表遞歸查找,false代表類似文件夾查找,以'/'分隔,不查子文件夾</param>
public static IObservable<Item> ListObjects(MinioClient minio, string bucketName, string prefix = null, bool recursive = true)
{
try
{
ListObjectsArgs args = new ListObjectsArgs()
.WithBucket(bucketName)
.WithPrefix(prefix)
.WithRecursive(recursive);
IObservable<Item> data = minio.ListObjectsAsync(args);
return data;
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
#endregion
#region 操作文件對象
public static bool FileExist(MinioClient minio, string bucketName, string objectName)
{
try
{
var obj = new StatObjectArgs().WithBucket(bucketName)
.WithObject(objectName);
var objStat = minio.StatObjectAsync(obj);
objStat.Wait();
}
catch (AggregateException e)
{
foreach (var item in e.InnerExceptions)
{
if(item is ObjectNotFoundException notFound)
{
return false;
}
}
}
return true;
}
/// <summary>
/// 從桶下載文件到流
/// </summary>
/// <param name="minio">連接實例</param>
/// <param name="bucketName">存儲桶名稱</param>
/// <param name="objectName">存儲桶里的對象名稱</param>
/// <param name="sse"></param>
/// <returns></returns>
public static Task<ObjectStat> FGetObject(MinioClient minio, string bucketName, string objectName, ServerSideEncryption sse = null, Action<Stream> cb = null)
{
CheckBucket(minio, bucketName);
try
{
GetObjectArgs args = new GetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithServerSideEncryption(sse)
.WithCallbackStream(cb);
return minio.GetObjectAsync(args);
}
catch (MinioException e)
{
throw new Exception(e.Message);
}
}
/// <summary>
/// 從桶下載文件到本地
/// </summary>
/// <param name="minio"></param>
/// <param name="bucketName"></param>
/// <param name="objectName"></param>
/// <param name="fileName"></param>
/// <param name="sse"></param>
/// <returns></returns>
public static Task<ObjectStat> FGetObject(MinioClient minio, string bucketName, string objectName, string fileName, ServerSideEncryption sse = null)
{
CheckBucket(minio, bucketName);
if (File.Exists(fileName))
{
File.Delete(fileName);
}
return FGetObject(minio, bucketName, objectName, sse, stream =>
{
using (FileStream fileStream = new FileStream(fileName, FileMode.CreateNew, FileAccess.Write))
{
stream.CopyTo(fileStream);
}
});
}
/// <summary>
/// 上傳本地文件至存儲桶
/// </summary>
/// <param name="minio">連接實例</param>
/// <param name="bucketName">存儲桶名稱</param>
/// <param name="objectName">存儲桶里的對象名稱</param>
/// <param name="fileName">本地路徑</param>
/// <returns></returns>
public static Task FPutObject(MinioClient minio, string bucketName, string objectName, string fileName, string contentType = "application/octet-stream", Dictionary<string, string> metaData = null, ServerSideEncryption sse = null)
{
CheckBucket(minio, bucketName);
try
{
//var data= minio.PutObjectAsync(bucketName, objectName, fileName, contentType: "application/octet-stream");
PutObjectArgs args = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithFileName(fileName)
.WithContentType(contentType)
.WithHeaders(metaData)
.WithServerSideEncryption(sse);
return minio.PutObjectAsync(args);
}
catch (MinioException e)
{
throw new Exception(e.Message);
}
}
#endregion
#region Presigned操作
/// <summary>生成一個給HTTP GET請求用的presigned URL。瀏覽器/移動端的客戶端可以用這個URL進行下載,即使其所在的存儲桶是私有的。這個presigned URL可以設置一個失效時間,默認值是7天。
/// 生成一個給HTTP GET請求用的presigned URL。瀏覽器/移動端的客戶端可以用這個URL進行下載,即使其所在的存儲桶是私有的。這個presigned URL可以設置一個失效時間,默認值是7天。
/// </summary>
/// <param name="minio">連接實例</param>
/// <param name="bucketName">存儲桶名稱</param>
/// <param name="objectName">存儲桶里的對象名稱</param>
/// <param name="expiresInt">失效時間(以秒為單位),默認是7天,不得大於七天</param>
/// <param name="reqParams">額外的響應頭信息,支持response-expires、response-content-type、response-cache-control、response-content-disposition</param>
/// <returns></returns>
public static Task<string> PresignedGetObject(MinioClient minio, string bucketName, string objectName, int expiresInt = 1000)
{
CheckBucket(minio, bucketName);
try
{
//Dictionary<string, string> reqParams = new Dictionary<string, string> { { "response-content-type", "application/json" } };
PresignedGetObjectArgs args = new PresignedGetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
//.WithHeaders(reqParams)
.WithExpiry(expiresInt);
//.WithRequestDate(DateTime.Now.ToUniversalTime());
return minio.PresignedGetObjectAsync(args);
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
/// <summary>生成一個給HTTP PUT請求用的presigned URL。瀏覽器/移動端的客戶端可以用這個URL進行上傳,即使其所在的存儲桶是私有的。這個presigned URL可以設置一個失效時間,默認值是7天。
/// 生成一個給HTTP PUT請求用的presigned URL。瀏覽器/移動端的客戶端可以用這個URL進行上傳,即使其所在的存儲桶是私有的。這個presigned URL可以設置一個失效時間,默認值是7天。
/// </summary>
/// <param name="minio">連接實例</param>
/// <param name="bucketName">存儲桶名稱</param>
/// <param name="objectName">存儲桶里的對象名稱</param>
/// <param name="expiresInt">失效時間(以秒為單位),默認是7天,不得大於七天</param>
/// <returns></returns>
public static Task<string> PresignedPutObject(MinioClient minio, string bucketName, string objectName, int expiresInt = 1000)
{
CheckBucket(minio, bucketName);
try
{
//string presignedUrl = await minio.PresignedPutObjectAsync(bucketName, objectName, expiresInt);
//Ret = presignedUrl;
//flag = true;
PresignedPutObjectArgs args = new PresignedPutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithExpiry(expiresInt);
return minio.PresignedPutObjectAsync(args);
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
/// <summary>允許給POST請求的presigned URL設置策略,比如接收對象上傳的存儲桶名稱的策略,key名稱前綴,過期策略。
/// 允許給POST請求的presigned URL設置策略,比如接收對象上傳的存儲桶名稱的策略,key名稱前綴,過期策略。
/// </summary>
/// <param name="minio">連接實例</param>
/// <param name="PostPolicy">對象的post策略</param>
/// <returns></returns>
public async static Task<(Uri, Dictionary<string, string>)> PresignedPostPolicy(MinioClient minio)
{
try
{
PostPolicy form = new PostPolicy();
DateTime expiration = DateTime.UtcNow;
form.SetExpires(expiration.AddDays(10));
form.SetKey("my-objectname");
form.SetBucket("my-bucketname");
(Uri, Dictionary<string, string>) data = await minio.PresignedPostPolicyAsync(form);
return data;
//tuple<uri, dictionary<string, string>> tuple =;
//string curlCommand = "curl -X POST ";
//foreach (KeyValuePair<string, string> pair in tuple.Item2)
//{
// curlCommand = curlCommand + $" -F {pair.Key}={pair.Value}";
//}
//curlCommand = curlCommand + " -F file=@/etc/bashrc " + tuple.Item1; // https://s3.amazonaws.com/my-bucketname";
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
#endregion
#region 操作對象
/// <summary>下載對象指定區域的字節數組做為流。offset和length都必須傳
/// 下載對象指定區域的字節數組做為流。offset和length都必須傳
/// </summary>
/// <param name="minio">連接實例</param>
/// <param name="bucketName">存儲桶名稱</param>
/// <param name="objectName">存儲桶里的對象名稱</param>
/// <param name="offset">offset 是起始字節的位置</param>
/// <param name="length">length是要讀取的長度</param>
/// <param name="callback">處理流的回調函數</param>
/// <returns></returns>
public async static Task GetObjectAsync(MinioClient minio, string bucketName, string objectName, long offset, long length, Action<Stream> callback)
{
CheckBucket(minio, bucketName);
try
{
StatObjectArgs args = new StatObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithServerSideEncryption(null);
await minio.StatObjectAsync(args);
GetObjectArgs objArgs = new GetObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithCallbackStream(callback)
.WithOffsetAndLength(offset, length)
.WithServerSideEncryption(null);
await minio.GetObjectAsync(objArgs);
}
catch (MinioException e)
{
throw new Exception(e.Message);
}
}
/// <summary>通過Stream上傳對象
/// 通過Stream上傳對象
/// </summary>
/// <param name="minio">連接實例</param>
/// <param name="bucketName">存儲桶名稱</param>
/// <param name="objectName">存儲桶里的對象名稱</param>
/// <param name="data">要上傳的Stream對象</param>
/// <param name="size">流的大小</param>
/// <param name="contentType">文件的Content type,默認是"application/octet-stream"</param>
/// <param name="metaData">元數據頭信息的Dictionary對象,默認是null</param>
/// <returns></returns>
public async static Task PutObjectAsync(MinioClient minio, string bucketName, string objectName, Stream data, long size, string contentType = "application/octet-stream", Dictionary<string, string> metaData = null)
{
CheckBucket(minio, bucketName);
try
{
//byte[] bs = File.ReadAllBytes(fileName);
//System.IO.MemoryStream filestream = new System.IO.MemoryStream(bs);
//await minio.PutObjectAsync(bucketName, objectName, data, size, contentType, metaData);
PutObjectArgs args = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(data)
.WithObjectSize(size)
.WithContentType(contentType)
.WithHeaders(metaData)
.WithServerSideEncryption(null);
await minio.PutObjectAsync(args);
}
catch (MinioException e)
{
throw new Exception(e.Message);
}
}
/// <summary>從objectName指定的對象中將數據拷貝到destObjectName指定的對象
/// 從objectName指定的對象中將數據拷貝到destObjectName指定的對象
/// </summary>
/// <param name="minio"></param>
/// <param name="fromBucketName">源存儲桶名稱</param>
/// <param name="fromObjectName">源存儲桶中的源對象名稱</param>
/// <param name="destBucketName">目標存儲桶名稱</param>
/// <param name="destObjectName">要創建的目標對象名稱,如果為空,默認為源對象名稱</param>
/// <param name="copyConditions">拷貝操作的一些條件Map</param>
/// <param name="sseSrc"></param>
/// <param name="sseDest"></param>
/// <returns></returns>
public async static Task CopyObject(MinioClient minio, string fromBucketName, string fromObjectName, string destBucketName, string destObjectName, CopyConditions copyConditions = null, ServerSideEncryption sseSrc = null, ServerSideEncryption sseDest = null, Dictionary<string, string> metadata = null)
{
CheckBucket(minio, fromBucketName);
CheckBucket(minio, destBucketName);
try
{
CopySourceObjectArgs cpSrcArgs = new CopySourceObjectArgs()
.WithBucket(fromBucketName)
.WithObject(fromObjectName)
.WithCopyConditions(copyConditions)
.WithServerSideEncryption(sseSrc);
CopyObjectArgs args = new CopyObjectArgs()
.WithBucket(destBucketName)
.WithObject(destObjectName)
.WithCopyObjectSource(cpSrcArgs)
.WithHeaders(metadata)
.WithServerSideEncryption(sseDest);
await minio.CopyObjectAsync(args);
}
catch (MinioException e)
{
throw new Exception(e.Message);
}
}
/// <summary>刪除一個對象
/// 刪除一個對象
/// </summary>
/// <param name="minio">連接實例</param>
/// <param name="bucketName">存儲桶名稱</param>
/// <param name="objectName">存儲桶里的對象名稱</param>
/// <returns></returns>
public static Task RemoveObject(MinioClient minio, string bucketName, string objectName)
{
CheckBucket(minio, bucketName);
try
{
RemoveObjectArgs args = new RemoveObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
return minio.RemoveObjectAsync(args);
}
catch (MinioException e)
{
throw new Exception(e.Message);
}
}
/// <summary>刪除多個對象
/// 刪除多個對象
/// </summary>
/// <param name="minio">連接實例</param>
/// <param name="bucketName">存儲桶名稱</param>
/// <param name="objectsList">含有多個對象名稱的IEnumerable</param>
/// <returns></returns>
public static async Task<bool> RemoveObjects(MinioClient minio, string bucketName, List<string> objectsList)
{
CheckBucket(minio, bucketName);
bool flag = false;
try
{
if (objectsList != null)
{
//IObservable<DeleteError> objectsOservable = await minio.RemoveObjectAsync(bucketName, objectsList).ConfigureAwait(false);
flag = true;
//IDisposable objectsSubscription = objectsOservable.Subscribe(
// objDeleteError => Console.WriteLine($"Object: {objDeleteError.Key}"),
// ex => Console.WriteLine($"OnError: {ex}"),
// () =>
// {
// Console.WriteLine($"Removed objects in list from {bucketName}\n");
// });
//return;
RemoveObjectsArgs args = new RemoveObjectsArgs()
.WithBucket(bucketName)
.WithObjects(objectsList);
await minio.RemoveObjectsAsync(args);
}
}
catch (MinioException e)
{
throw new Exception(e.Message);
}
return flag;
}
#endregion
}
//獲取上傳鏈接
var minio = MinioHelper.Create("127.0.0.1", "minioadmin", "minioadmin");
var putUrlData = MinioHelper.PresignedPutObject(minio, "", "");
putUrlData.Wait();
linux環境下minio部署
wget https://dl.min.io/server/minio/release/linux-amd64/minio_20220917000945.0.0_amd64.deb
dpkg -i minio_20220917000945.0.0_amd64.deb
# MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password minio server /mnt/data --console-address ":9001"
/etc/systemd/system路徑下創建文件minio.service
[Unit]
Description=api services
[Service]
Type=forking
ExecStart=/Server/startMinio.sh
#ExecReload=/Service/API/RunDotNetServices.sh
#ExecStop=/Service/API/RunDotNetServices.sh
PrivateTmp=true
[Install]
WantedBy=multi-user.target
其中/Server/startMinio.sh內如如下
#!/bin/bash
/usr/local/bin/minio server /Server/miniodata --address :7000 --console-address :7001 &
配置開機啟動
systemctl enable /etc/systemd/system/minio.service