最近更新时间:2023-01-11 10:41:05
此SDK适用于.net framework4.0及以上版本。基于KS3 API 构建。使用此 SDK 构建您的网络应用程序,能让您以非常便捷地方式将数据安全地存储到金山云存储上。无论您的网络应用是一个网站程序,还是包括从云端(服务端程序)到终端(手持设备应用)的架构的服务或应用,通过KS3存储及其 SDK,都能让您应用程序的终端用户高速上传和下载,同时也让您的服务端更加轻盈。
配置.net framework4.0 以上开发环境
由于在App端明文存储AccessKey、SecretKey是极不安全的,因此推荐的使用场景如下图所示:
1. 开通KS3服务,https://www.ksyun.com/user/register 注册账号
2. 进入控制台, https://ks3.console.ksyun.com/console.html#/setting 获取AccessKeyID 、AccessKeySecret
当以上全部完成之后用户便可初始化客户端进行操作
String accessKey = "YOUR ACCESS KEY";
String secretKey = "YOUR SECRET KEY";
String bucketName = "YOUR BUCKET NAME";
String endPoint = "ks3-cn-beijing.ksyuncs.com"; //此处以北京region为例
ks3Client = new KS3Client(accessKey, secretKey);
ks3Client.setEndpoint(endPoint);
在KS3中,用户操作的基本数据单元是Object。单个Object允许存储0~48.8TB的数据。 Object 包含key和data。其中,key是Object的名字;data是Object 的数据。key为UTF-8编码,且编码后的长度不得超过1024个字符。
即Object的名字,key为UTF-8编码,且编码后的长度不得超过1024个字符。Key中可以带有斜杠,当Key中带有斜杠的时候,将会自动在控制台里组织成目录结构。
其他术语请参考概念与术语
列出当前用户的所有bucket,可以查看每个bucket的名称、创建时间以及所有者
private static bool listBuckets()
{
// List Buckets
try
{
IList < Bucket > bucketsList = ks3Client.listBuckets();
foreach(Bucket b in bucketsList)
{
Console.WriteLine(b.ToString());
}
}
catch(System.Exception e)
{
return false;
}
return true;
}
删除一个Bucket
private static bool deleteBucket()
{
// Delete Bucket
try
{
ks3Client.deleteBucket(bucketName);
}
catch(System.Exception e)
{
return false;
}
return true;
}
列出<bucket名称>
下的所有object,最大上限是1000个
private static bool listObjects()
{
try
{
// List Objects
Console.WriteLine("--- List Objects: ---");
ObjectListing objects = ks3Client.listObjects(bucketName);
Console.WriteLine(objects.ToString());
Console.WriteLine("---------------------\n");
// Get Object Metadata
Console.WriteLine("--- Get Object Metadata ---");
ObjectMetadata objMeta = ks3Client.getObjectMetadata(bucketName, objKeyName);
Console.WriteLine(objMeta.ToString());
Console.WriteLine("---------------------------\n");
}
catch(System.Exception e)
{
Console.WriteLine(e.ToString());
return false;
}
return true;
}
获取<bucket名称>
的acl控制权限
private static bool getBucketACL()
{
// 获取 Bucket ACL
try
{
Console.WriteLine("--- Get Bucket ACL: ---");
AccessControlList acl = ks3Client.getBucketAcl(bucketName);
Console.WriteLine("Bucket Name: " + bucketName);
Console.WriteLine(acl.ToString());
Console.WriteLine("-----------------------\n");
}
catch(System.Exception e)
{
Console.WriteLine(e.ToString());
return false;
}
return true;
}
列出当前正在执行的分块上传
private static ListMultipartUploadsResult listMultipartUploads(string bucket, string objKey, string uploadId) {
ListMultipartUploadsRequest request = new ListMultipartUploadsRequest(bucket, objKey, uploadId);
ListMultipartUploadsResult result = ks3Client.getListMultipartUploads(request);
return result;
}
新建一个<bucket名称>
private static bool createBucket()
{
// Create Bucket
try
{
Console.WriteLine("--- Create Bucket: ---");
Console.WriteLine("Bucket Name: " + bucketName);
Bucket bucket = ks3Client.createBucket(bucketName);
Console.WriteLine("Success.");
Console.WriteLine("----------------------\n");
}
catch(System.Exception e)
{
Console.WriteLine("Create Bucket Fail! " + e.ToString());
return false;
}
return true;
}
注:这里如果出现409 conflict错误,说明请求的bucket name有冲突,因为bucket name是全局唯一的
设置<bucket名称>
的访问权限
private static bool setBucketACL()
{
// 为bucket设置公共读写权限
try
{
Console.WriteLine("--- Set Bucket ACL: ---");
CannedAccessControlList cannedAcl = new CannedAccessControlList(CannedAccessControlList.PUBLICK_READ_WRITE);
ks3Client.setBucketAcl(bucketName, cannedAcl);
Console.WriteLine("Bucket Name: " + bucketName);
Console.WriteLine("Success, now the ACL is:\n" + ks3Client.getBucketAcl(bucketName));
Console.WriteLine("-----------------------\n");
}
catch(System.Exception e)
{
Console.WriteLine(e.ToString());
return false;
}
return true;
}
删除<bucket名称>
内一个object
private static bool deleteObject()
{
// Delete Object
try
{
Console.WriteLine("--- Delete Object: ---");
ks3Client.deleteObject(bucketName, objKeyName);
Console.WriteLine("Delete Object completed.");
Console.WriteLine("---------------------\n");
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
return false;
}
return true;
}
下载<bucket名称>
下的object
private static bool getObject() {
try {
// GET Object为用户提供了object的下载,用户可以通过控制Range实现分块多线程下载
Console.WriteLine("--- Download and Store in Memory ---");
GetObjectRequest getShortContent = new GetObjectRequest(bucketName, objKeyName);
getShortContent.setRange(0, 24);
KS3Object ks3Object = ks3Client.getObject(getShortContent);
StreamReader sr = new StreamReader(ks3Object.getObjectContent());
Console.WriteLine("Content:\n" + sr.ReadToEnd());
sr.Close();
ks3Object.getObjectContent().Close();
Console.WriteLine("------------------------------------\n");
} catch(System.Exception e) {
Console.WriteLine(e.ToString());
return false;
}
try {
// 直接下载并存储成文件
Console.WriteLine("--- Download a File ---");
// I need to get the Content-Length to set the listener.
ObjectMetadata objectMetadata = ks3Client.getObjectMetadata(bucketName, objKeyName);
SampleListener downloadListener = new SampleListener(objectMetadata.getContentLength());
GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objKeyName, new FileInfo(outFilePath));
getObjectRequest.setProgressListener(downloadListener);
KS3Object obj = ks3Client.getObject(getObjectRequest);
obj.getObjectContent().Close(); // The file was opened in [KS3ObjectResponseHandler], so I close it first.
Console.WriteLine("Success. See the file downloaded at {0}", outFilePath);
Console.WriteLine("-----------------------\n");
} catch(System.Exception e) {
Console.WriteLine(e.ToString());
return false;
}
return true;
}
获取 <bucket名称>
这个bucket下<object key>
的权限控制信息
private static bool getObjectACL()
{
//获取 Object ACL
try
{
Console.WriteLine("--- Get Object ACL: ---");
AccessControlList acl = ks3Client.getObjectAcl(bucketName, objKeyName);
Console.WriteLine("Object Key: " + objKeyName);
Console.WriteLine(acl.ToString());
Console.WriteLine("-----------------------\n");
}
catch(System.Exception e)
{
Console.WriteLine(e.ToString());
return false;
}
return true;
}
将new File("<filePath>")
这个文件上传至<bucket名称>这个存储空间下,并命名为<object key>
private static bool putObject()
{
try
{
//Put Object(upload a short content)
//以流方式上传文件到KS3,Content-Type 默认为 application/octet-stream
Console.WriteLine("--- Upload a Short Content: ---");
String sampleContent = "This is a sample content.(25 characters before, included the 4 spaces)";
Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(sampleContent));
PutObjectResult shortContentResult = ks3Client.putObject(bucketName, objKeyName, stream, null);
Console.WriteLine("Upload Completed. eTag=" + shortContentResult.getETag() + ", MD5=" + shortContentResult.getContentMD5());
Console.WriteLine("-------------------------------\n");
//Put Object(upload a file)
//以文件方式上传到KS3时,Content-Type 会默认匹配上传文件的后缀名
Console.WriteLine("--- Upload a File ---");
FileInfo file = new FileInfo("E:\\tool\\eclipse.rar");
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objKeyName, file);
SampleListener sampleListener = new SampleListener(file.Length);
putObjectRequest.setProgressListener(sampleListener);
PutObjectResult putObjectResult = ks3Client.putObject(putObjectRequest);
Console.WriteLine("Upload Completed. eTag=" + putObjectResult.getETag() + ", MD5=" + putObjectResult.getContentMD5());
Console.WriteLine("---------------------\n");
}
catch(System.Exception e)
{
Console.WriteLine(e.ToString());
return false;
}
return true;
}
修改<bucket名称>
下object的权限控制
private static bool setObjectACL()
{
// 设置Object ACL为公共读写
try
{
Console.WriteLine("--- Set Object ACL: ---");
CannedAccessControlList cannedAcl = new CannedAccessControlList(CannedAccessControlList.PUBLICK_READ_WRITE);
Console.WriteLine("Object Key: " + objKeyName);
ks3Client.setObjectAcl(bucketName, objKeyName, cannedAcl);
Console.WriteLine("Success, now the ACL is:\n" + ks3Client.getObjectAcl(bucketName, objKeyName));
Console.WriteLine("-----------------------\n");
}
catch(System.Exception e)
{
Console.WriteLine(e.ToString());
return false;
}
return true;
}
/**
* 初始化分块上传,服务端会返回一个全局唯一的uploadid
* **/
private static InitiateMultipartUploadResult multipartUp()
{
InitiateMultipartUploadResult re=ks3Client.initiateMultipartUpload(bucketName, objKeyName);
Console.WriteLine(re.ToString());
return re;
}
/**
* 分块上传例子
* **/
private static bool uploadPart() {
string path = @"you file path";//上传文件路径,例如E:\tool\aa.rar
InitiateMultipartUploadResult result=multipartUp();
FileInfo file = new FileInfo(path);
int part = 5 * 1024 * 1024;
int numBytesToRead = (int)file.Length;
int i = 0;
XElement root = new XElement("CompleteMultipartUpload");//初始化一个xml,以备分块上传完成后调用complete方法提交本次上传的文件以通知服务端合并分块
//开始读取文件
using (FileStream fs = new FileStream(path, FileMode.Open))
{
while (numBytesToRead > 0)
{
UploadPartRequest request = new UploadPartRequest(
result.getBucket(), result.getKey(), result.getUploadId(),
i + 1);
//每次读取5M文件内容,如果最后一次内容不及5M则按实际大小取值
int count = Convert.ToInt32((i * part + part) > file.Length ? file.Length - i * part : part);
byte[] data = new byte[count];
int n = fs.Read(data, 0, count);
request.setInputStream(new MemoryStream(data));
ProgressListener sampleListener = new SampleListener(count);//实例一个更新进度的监听类,实际使用中可自己定义实现
request.setProgressListener(sampleListener);
PartETag tag = ks3Client.uploadPart(request);//上传本次分块内容
Console.WriteLine(tag.ToString());
if (n == 0)
break;
numBytesToRead -= n;
XElement partE = new XElement("Part");
partE.Add(new XElement("PartNumber", i + 1));
partE.Add(new XElement("ETag", tag.geteTag()));
root.Add(partE);
i++;
}
}
//所有分块上传完成后发起complete request,通知服务端合并分块
CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest(result.getBucket(), result.getKey(), result.getUploadId());
completeRequest.setContent(new MemoryStream(System.Text.Encoding.Default.GetBytes(root.ToString())));
CompleteMultipartUploadResult completeResult = ks3Client.completeMultipartUpload(completeRequest);
return true;
}
/**
* 放弃本次上传
* **/
private static bool AbortMultipartUpload(string bucket, string objKey, string uploadId)
{
AbortMultipartUploadRequest request = new AbortMultipartUploadRequest(bucket, objKey, uploadId);
ks3Client.AbortMultipartUpload(request);
return true;
}
/**
* 多线程分块上传例子开始
* **/
static List<ManualResetEvent> manualEvents = new List<ManualResetEvent>();
static List<Param> paras = new List<Param>();
private static bool uploadPartMultithread()
{
string path = inFilePath;//上传文件路径,例如E:\tool\aa.rar
InitiateMultipartUploadResult result = multipartUp();
FileInfo file = new FileInfo(path);
int part = 5 * 1024 * 1024;
int numBytesToRead = (int)file.Length;
int i = 0;
XElement root = new XElement("CompleteMultipartUpload");//初始化一个xml,以备分块上传完成后调用complete方法提交本次上传的文件以通知服务端合并分块
//开始读取文件
using (FileStream fs = new FileStream(path, FileMode.Open))
{
while (numBytesToRead > 0)
{
UploadPartRequest request = new UploadPartRequest(
result.getBucket(), result.getKey(), result.getUploadId(),
i + 1);
//每次读取5M文件内容,如果最后一次内容不及5M则按实际大小取值
int count = Convert.ToInt32((i * part + part) > file.Length ? file.Length - i * part : part);
byte[] data = new byte[count];
int n = fs.Read(data, 0, count);
request.setInputStream(new MemoryStream(data));
ManualResetEvent mre = new ManualResetEvent(false);
manualEvents.Add(mre);
Param pra = new Param();
pra.mrEvent = mre;
pra.praNum = i + 1;
pra.request = request;
paras.Add(pra);
ThreadPool.QueueUserWorkItem(new WaitCallback(uploadPartTask), pra);
if (n == 0)
break;
numBytesToRead -= n;
i++;
}
}
WaitHandle.WaitAll(manualEvents.ToArray());
for (int j = 0; j < paras.Count; j++)
{
XElement partE = new XElement("Part");
partE.Add(new XElement("PartNumber", paras[j].praNum));
partE.Add(new XElement("ETag", paras[j].etag));
Console.WriteLine("==" + paras[j].praNum + ", etag=" + paras[j].etag);
root.Add(partE);
}
//所有分块上传完成后发起complete request,通知服务端合并分块
CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest(result.getBucket(), result.getKey(), result.getUploadId());
completeRequest.setContent(new MemoryStream(System.Text.Encoding.Default.GetBytes(root.ToString())));
CompleteMultipartUploadResult completeResult = ks3Client.completeMultipartUpload(completeRequest);
return true;
}
private static void uploadPartTask(Object obj) {
Param pra = (Param)obj;
UploadPartRequest request = pra.request;
PartETag tag = ks3Client.uploadPart(request);//上传本次分块内容
if (tag.geteTag() != null) {
pra.etag = tag.geteTag();
pra.mrEvent.Set();
Console.WriteLine(tag.ToString());
}
}
public class Param
{
public ManualResetEvent mrEvent;
public UploadPartRequest request;
public int praNum;
public string etag;
}
/**
* 多线程分块上传例子结束
* */
注:中途想停止分块上传的话请调用AbortMultipartUpload(bucketname, objectkey, uploadId);
private static void getObjUrl() {
DateTime date = DateTime.Now;
date=date.AddMinutes(5);//指定签名有效期
String url = ks3Client.generatePresignedUrl("YourBucketName", "YourKey", date);
Console.WriteLine("url:"+url);
}
纯净模式