C#上传文件到阿里云OSS
1.引入必须的dll文件,下载地址:
2.解压,在bin目录下找到:Aliyun.OSS.dll文件,引入项目
3.引入命名空间:using Aliyun.OSS;
4.源代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aliyun.OSS;
using System.Threading;
using System.IO;
namespace Push
{
public class MultipartUploadSample
{
/// <summary>
/// 登录OSS控制台必须的key
/// </summary>
public static string accessKeyId = System.Configuration.ConfigurationSettings.AppSettings["accessKeyId"];
/// <summary>
/// 登录OSS控制台必须的value
/// </summary>
public static string accessKeySecret = System.Configuration.ConfigurationSettings.AppSettings["accessKeySecret"];
/// <summary>
/// 域名,OSS控制台里能绑定自己的域名,没有自己的域名也无妨,默认是阿里云提供的域名地址
/// </summary>
public static string endpoint = System.Configuration.ConfigurationSettings.AppSettings["endpoint"];
/// <summary>
/// OSS存储空间的名称
/// </summary>
public static string bucketName = System.Configuration.ConfigurationSettings.AppSettings["bucketName"];
/// <summary>
/// 初始化阿里云存储空间对象
/// </summary>
static OssClient client = new OssClient(endpoint, accessKeyId, accessKeySecret);
/// <summary>
/// 设置分片上传的每一片的大小为50M
/// </summary>
static int partSize = 50 * 1024 * 1024;
public class UploadPartContext
{
public string BucketName { get; set; }
public string ObjectName { get; set; }
public List<PartETag> PartETags { get; set; }
public string UploadId { get; set; }
public long TotalParts { get; set; }
public long CompletedParts { get; set; }
public object SyncLock { get; set; }
public ManualResetEvent WaitEvent { get; set; }
}
public class UploadPartContextWrapper
{
public UploadPartContext Context { get; set; }
public int PartNumber { get; set; }
public Stream PartStream { get; set; }
public UploadPartContextWrapper(UploadPartContext context, Stream partStream, int partNumber)
{
Context = context;
PartStream = partStream;
PartNumber = partNumber;
}
}
public class UploadPartCopyContext
{
public string TargetBucket { get; set; }
public string TargetObject { get; set; }
public List<PartETag> PartETags { get; set; }
public string UploadId { get; set; }
public long TotalParts { get; set; }
public long CompletedParts { get; set; }
public object SyncLock { get; set; }
public ManualResetEvent WaitEvent { get; set; }
}
public class UploadPartCopyContextWrapper
{
public UploadPartCopyContext Context { get; set; }
public int PartNumber { get; set; }
public UploadPartCopyContextWrapper(UploadPartCopyContext context, int partNumber)
{
Context = context;
PartNumber = partNumber;
}
}
/// <summary>
///大文件分片上传
/// </summary>
/// <param name="bucketName">OSS存储空间名称</param>
public static void UploadMultipart(String bucketName,String fileName,String localFilePath)
{
//初始化一个分片上传事件
var uploadId = InitiateMultipartUpload(bucketName, fileName);
var partETags = UploadParts(bucketName, fileName, localFilePath, uploadId, partSize);
CompleteUploadPart(bucketName, fileName, uploadId, partETags);
//Console.WriteLine("Multipart put object:{0} succeeded", key);
}
/// <summary>
/// 异步分片上传。
/// </summary>
public static void AsyncUploadMultipart(String bucketName,String fileName,string localFilePath)
{
var uploadId = InitiateMultipartUpload(bucketName, fileName);
AsyncUploadParts(bucketName, fileName, localFilePath, uploadId, partSize);
}
/// <summary>
/// 分片拷贝。
/// </summary>
public static void UploadMultipartCopy(String targetBucket, String targetObject, String sourceBucket, String sourceObject)
{
var uploadId = InitiateMultipartUpload(targetBucket, targetObject);
var partETags = UploadPartCopys(targetBucket, targetObject, sourceBucket, sourceObject, uploadId, partSize);
var completeResult = CompleteUploadPart(targetBucket, targetObject, uploadId, partETags);
Console.WriteLine(@"Upload multipart copy result : ");
Console.WriteLine(completeResult.Location);
}
/// <summary>
/// 异步分片拷贝。
/// </summary>
public static void AsyncUploadMultipartCopy(String targetBucket, String targetObject, String sourceBucket, String sourceObject)
{
var uploadId = InitiateMultipartUpload(targetBucket, targetObject);
AsyncUploadPartCopys(targetBucket, targetObject, sourceBucket, sourceObject, uploadId, partSize);
}
/// <summary>
/// 列出所有执行中的Multipart Upload事件
/// </summary>
/// <param name="bucketName">目标bucket名称</param>
public static void ListMultipartUploads(String bucketName)
{
var listMultipartUploadsRequest = new ListMultipartUploadsRequest(bucketName);
var result = client.ListMultipartUploads(listMultipartUploadsRequest);
Console.WriteLine("Bucket name:" + result.BucketName);
Console.WriteLine("Key marker:" + result.KeyMarker);
Console.WriteLine("Delimiter:" + result.Delimiter);
Console.WriteLine("Prefix:" + result.Prefix);
Console.WriteLine("UploadIdMarker:" + result.UploadIdMarker);
foreach (var part in result.MultipartUploads)
{
Console.WriteLine(part.ToString());
}
}
/// <summary>
/// 初始化一个分片上传事件
/// </summary>
/// <param name="bucketName">存储空间名称</param>
/// <param name="objectName"></param>
/// <returns></returns>
public static string InitiateMultipartUpload(String bucketName, String objectName)
{
var request = new InitiateMultipartUploadRequest(bucketName, objectName);
var result = client.InitiateMultipartUpload(request);
return result.UploadId;
}
/// <summary>
/// 上传分片
/// </summary>
/// <param name="bucketName">OSS存储空间名称</param>
/// <param name="objectName">上传到OSS后的文件名称</param>
/// <param name="fileToUpload">本地待上传的文件</param>
/// <param name="uploadId">上传编号</param>
/// <param name="partSize">分片大小</param>
/// <returns>分片集合</returns>
public static List<PartETag> UploadParts(String bucketName, String objectName, String fileToUpload,
String uploadId, int partSize)
{
var fi = new FileInfo(fileToUpload);
var fileSize = fi.Length;
var partCount = fileSize / partSize;
if (fileSize % partSize != 0)
{
partCount++;
}
var partETags = new List<PartETag>();
using (var fs = File.Open(fileToUpload, FileMode.Open))
{
for (var i = 0; i < partCount; i++)
{
var skipBytes = (long)partSize * i;
fs.Seek(skipBytes, 0);
var size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
var request = new UploadPartRequest(bucketName, objectName, uploadId)
{
InputStream = fs,
PartSize = size,
PartNumber = i + 1
};
var result = client.UploadPart(request);
partETags.Add(result.PartETag);
Console.WriteLine("finish {0}/{1}", partETags.Count, partCount);
}
}
return partETags;
}
public static void AsyncUploadParts(String bucketName, String objectName, String fileToUpload,
String uploadId, int partSize)
{
var fi = new FileInfo(fileToUpload);
var fileSize = fi.Length;
var partCount = fileSize / partSize;
if (fileSize % partSize != 0)
{
partCount++;
}
var ctx = new UploadPartContext()
{
BucketName = bucketName,
ObjectName = objectName,
UploadId = uploadId,
TotalParts = partCount,
CompletedParts = 0,
SyncLock = new object(),
PartETags = new List<PartETag>(),
WaitEvent = new ManualResetEvent(false)
};
for (var i = 0; i < partCount; i++)
{
var fs = new FileStream(fileToUpload, FileMode.Open, FileAccess.Read, FileShare.Read);
var skipBytes = (long)partSize * i;
fs.Seek(skipBytes, 0);
var size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
var request = new UploadPartRequest(bucketName, objectName, uploadId)
{
InputStream = fs,
PartSize = size,
PartNumber = i + 1
};
client.BeginUploadPart(request, UploadPartCallback, new UploadPartContextWrapper(ctx, fs, i + 1));
}
ctx.WaitEvent.WaitOne();
}
public static void UploadPartCallback(IAsyncResult ar)
{
var result = client.EndUploadPart(ar);
var wrappedContext = (UploadPartContextWrapper)ar.AsyncState;
wrappedContext.PartStream.Close();
var ctx = wrappedContext.Context;
lock (ctx.SyncLock)
{
var partETags = ctx.PartETags;
partETags.Add(new PartETag(wrappedContext.PartNumber, result.ETag));
ctx.CompletedParts++;
Console.WriteLine("finish {0}/{1}", ctx.CompletedParts, ctx.TotalParts);
if (ctx.CompletedParts == ctx.TotalParts)
{
partETags.Sort((e1, e2) => (e1.PartNumber - e2.PartNumber));
var completeMultipartUploadRequest =
new CompleteMultipartUploadRequest(ctx.BucketName, ctx.ObjectName, ctx.UploadId);
foreach (var partETag in partETags)
{
completeMultipartUploadRequest.PartETags.Add(partETag);
}
var completeMultipartUploadResult = client.CompleteMultipartUpload(completeMultipartUploadRequest);
Console.WriteLine(@"Async upload multipart result : " + completeMultipartUploadResult.Location);
ctx.WaitEvent.Set();
}
}
}
public static List<PartETag> UploadPartCopys(String targetBucket, String targetObject, String sourceBucket, String sourceObject,
String uploadId, int partSize)
{
var metadata = client.GetObjectMetadata(sourceBucket, sourceObject);
var fileSize = metadata.ContentLength;
var partCount = (int)fileSize / partSize;
if (fileSize % partSize != 0)
{
partCount++;
}
var partETags = new List<PartETag>();
for (var i = 0; i < partCount; i++)
{
var skipBytes = (long)partSize * i;
var size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
var request =
new UploadPartCopyRequest(targetBucket, targetObject, sourceBucket, sourceObject, uploadId)
{
PartSize = size,
PartNumber = i + 1,
BeginIndex = skipBytes
};
var result = client.UploadPartCopy(request);
partETags.Add(result.PartETag);
}
return partETags;
}
public static void AsyncUploadPartCopys(String targetBucket, String targetObject, String sourceBucket, String sourceObject,
String uploadId, int partSize)
{
var metadata = client.GetObjectMetadata(sourceBucket, sourceObject);
var fileSize = metadata.ContentLength;
var partCount = (int)fileSize / partSize;
if (fileSize % partSize != 0)
{
partCount++;
}
var ctx = new UploadPartCopyContext()
{
TargetBucket = targetBucket,
TargetObject = targetObject,
UploadId = uploadId,
TotalParts = partCount,
CompletedParts = 0,
SyncLock = new object(),
PartETags = new List<PartETag>(),
WaitEvent = new ManualResetEvent(false)
};
for (var i = 0; i < partCount; i++)
{
var skipBytes = (long)partSize * i;
var size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
var request =
new UploadPartCopyRequest(targetBucket, targetObject, sourceBucket, sourceObject, uploadId)
{
PartSize = size,
PartNumber = i + 1,
BeginIndex = skipBytes
};
client.BeginUploadPartCopy(request, UploadPartCopyCallback, new UploadPartCopyContextWrapper(ctx, i + 1));
}
ctx.WaitEvent.WaitOne();
}
public static void UploadPartCopyCallback(IAsyncResult ar)
{
var result = client.EndUploadPartCopy(ar);
var wrappedContext = (UploadPartCopyContextWrapper)ar.AsyncState;
var ctx = wrappedContext.Context;
lock (ctx.SyncLock)
{
var partETags = ctx.PartETags;
partETags.Add(new PartETag(wrappedContext.PartNumber, result.ETag));
ctx.CompletedParts++;
if (ctx.CompletedParts == ctx.TotalParts)
{
partETags.Sort((e1, e2) => (e1.PartNumber - e2.PartNumber));
var completeMultipartUploadRequest =
new CompleteMultipartUploadRequest(ctx.TargetBucket, ctx.TargetObject, ctx.UploadId);
foreach (var partETag in partETags)
{
completeMultipartUploadRequest.PartETags.Add(partETag);
}
var completeMultipartUploadResult = client.CompleteMultipartUpload(completeMultipartUploadRequest);
Console.WriteLine(@"Async upload multipart copy result : " + completeMultipartUploadResult.Location);
ctx.WaitEvent.Set();
}
}
}
/// <summary>
/// 完成分片上传
/// </summary>
/// <param name="bucketName">OSS存储空间名称</param>
/// <param name="objectName">OSS存储空间上的文件名称</param>
/// <param name="uploadId">上传编号</param>
/// <param name="partETags">分片集合</param>
/// <returns></returns>
public static CompleteMultipartUploadResult CompleteUploadPart(String bucketName, String objectName,String uploadId, List<PartETag> partETags)
{
var completeMultipartUploadRequest =
new CompleteMultipartUploadRequest(bucketName, objectName, uploadId);
foreach (var partETag in partETags)
{
completeMultipartUploadRequest.PartETags.Add(partETag);
}
return client.CompleteMultipartUpload(completeMultipartUploadRequest);
}
/// <summary>
/// 上传一个新文件
/// </summary>
public static void PutObject(string _bucketName, string _key, string _fileToUpload)
{
try
{
client.PutObject(_bucketName, _key, _fileToUpload);
// Console.WriteLine("上传文件成功");
}
catch (Exception ex)
{
string msg = ex.Message;
//Console.WriteLine("上传文件失败.原因: {0}", ex.Message);
}
}
}
}
5.调用
var file = new FileInfo(newFilePath);
//节目大于50M分片上传
if (file.Length > 50 * 1024 * 1024)
{
MultipartUploadSample.UploadMultipart(MultipartUploadSample.bucketName, newFileName, newFilePath);
}
else
{
MultipartUploadSample.PutObject(MultipartUploadSample.bucketName, newFileName, newFilePath);
}
6.阿里云官网上传文件参考地址:
https://helpcdn.aliyun.com/document_detail/32090.html?spm=5176.doc32088.6.726.h0zvbb
不积跬步,无以至千里;不积小流,无以成江海。ヾ(◍°∇°◍)ノ゙