.NET 使用 Azure Blob 存儲圖片或文件

使用的是VS2017html

1、先使用 NuGet 獲取這兩個包。 執行如下步驟:web

在「解決方案資源管理器」中,右鍵單擊你的項目並選擇「管理 NuGet 包」。canvas

1.在線搜索「WindowsAzure.Storage」,而後單擊「安裝」 以安裝存儲客戶端庫和依賴項。api

2.在線搜索「WindowsAzure.ConfigurationManager」,而後單擊「安裝」以安裝 Azure Configuration Manager。cookie

會生成5個dll,以下圖:網絡

封裝代碼以下:app

須要先引用異步

using Microsoft.Azure;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;

1).AzureBlob.cside

public class AzureBlob
{
    #region 私有變量
    //類的成員,用於建立Blob服務客戶端
    CloudBlobClient blobClient;

    //容器和Blob其實就至關於文件夾、文件名

    /// <summary>
    /// 鏈接字符串
    /// </summary>
    private string storageConnectionString = CloudConfigurationManager.GetSetting("StorageConnectionString");
    #endregion

    #region 構造函數建立Blob服務客戶端
    public AzureBlob()
    {
        //解析配置中的鏈接字符串
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConnectionString);
        //建立Blob服務客戶端
        blobClient = storageAccount.CreateCloudBlobClient();
    }
    #endregion

    #region 獲取塊Blob引用
    /// <summary>
    /// 獲取塊Blob引用
    /// </summary>
    /// <param name="mycontainer">容器名</param>
    /// <param name="fileName">文件名</param>
    /// <returns></returns>
    public CloudBlockBlob GetContainer(string mycontainer, string fileName)
    {
        //獲取容器的引用
        CloudBlobContainer container = blobClient.GetContainerReference(mycontainer);
        //獲取塊 Blob 引用
        CloudBlockBlob blob = container.GetBlockBlobReference(fileName);
        return blob;
    }
    #endregion

    #region 二進制形式上傳文件
    /// <summary>
    /// 二進制形式上傳文件
    /// </summary>
    /// <param name="fileName">文件名</param>
    /// <param name="mycontainer">容器名</param>
    /// <param name="bytes">二進制形式的文件</param>
    /// <returns>異步信息</returns>
    public Task UploadToBlob(string fileName,string mycontainer,byte[] bytes)
    {
        //獲取容器的引用
        CloudBlobContainer container = blobClient.GetContainerReference(mycontainer);
        //建立一個容器(若是該容器不存在)
        container.CreateIfNotExists();
        //設置該容器爲公共容器,也就是說網絡上能訪問容器中的文件,但不能修改、刪除
        container.SetPermissions(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Blob });
        //將Blob(文件)上載到容器中,若是已存在同名Blob,則覆蓋它
        CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);//獲取塊 Blob 引用
        Task result = blockBlob.UploadFromByteArrayAsync(bytes, 0, bytes.Length);//將二進制文件上傳
        return result;
    }
    #endregion

    #region 文件路徑上傳
    /// <summary>
    /// 文件路徑上傳
    /// </summary>
    /// <param name="fileName">文件名</param>
    /// <param name="mycontainer">容器名</param>
    /// <param name="filePath">文件路徑</param>
    /// <returns></returns>
    public string UploadToBlob(string fileName, string mycontainer,string filePath)
    {
        ////獲取容器的引用
        CloudBlobContainer container = blobClient.GetContainerReference(mycontainer);
        //建立一個容器(若是該容器不存在)
        container.CreateIfNotExists();
        //設置該容器爲公共容器,也就是說網絡上能訪問容器中的文件,但不能修改、刪除
        container.SetPermissions(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Blob });
        //將Blob(文件)上載到容器中,若是已存在同名Blob,則覆蓋它
        CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);//獲取塊 Blob 引用
        //文件路徑
        using (var fileStream = System.IO.File.OpenRead(filePath))
        {
            blockBlob.UploadFromStream(fileStream);
        }
        return blockBlob.Uri.ToString();
    }
    #endregion

    #region 根據文件名和容器名取到Blob地址
    /// <summary>
    /// 根據文件名和容器名取到Blob地址
    /// </summary>
    /// <param name="fileName">文件名</param>
    /// <param name="mycontainer">容器名</param>
    /// <returns></returns>
    public string GetBlobURI(string fileName, string mycontainer)
    {
        CloudBlockBlob blob = GetContainer(mycontainer, fileName);
        return blob.Uri.ToString();
    }
    #endregion

    #region 下載Blob
    /// <summary>
    /// 下載Blob
    /// </summary>
    /// <param name="fileName">文件名</param>
    /// <param name="mycontainer">容器名</param>
    /// <param name="fliePath">文件路徑</param>
    public void DownloadToFile(string fileName, string mycontainer, string fliePath)
    {
        CloudBlockBlob blob = GetContainer(mycontainer, fileName);
        using (var fileStream = File.OpenWrite(fliePath))
        {
            blob.DownloadToStream(fileStream); //將blob保存在指定路徑
        }
    }
    #endregion

    #region 下載Blob
    /// <summary>
    /// 下載Blob
    /// </summary>
    /// <param name="fileName">文件名</param>
    /// <param name="mycontainer">容器名</param>
    /// <param name="fliePath">文件路徑</param>
    public string DownloadToStream(string fileName, string mycontainer)
    {
        CloudBlockBlob blob = GetContainer(mycontainer, fileName);
        string text;
        using (var memoryStream = new MemoryStream())
        {
            blob.DownloadToStream(memoryStream);
            text = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
        }
        return text;
    }
    #endregion

    #region 下載Blob
    /// <summary>
    /// 下載Blob
    /// </summary>
    /// <param name="fileName">文件名</param>
    /// <param name="mycontainer">容器名</param>
    /// <param name="fliePath">文件路徑</param>
    public void DownloadToFileStream(string fileName, string mycontainer, string fliePath)
    {
        CloudBlockBlob blob = GetContainer(mycontainer, fileName);
        using (var fileStream = new FileStream(fliePath, FileMode.OpenOrCreate))
        {
            blob.DownloadToStream(fileStream); //將blob保存在指定路徑
        };
    }
    #endregion

    #region 刪除Blob
    /// <summary>
    /// 刪除Blob
    /// </summary>
    /// <param name="fileName">文件名</param>
    /// <param name="mycontainer">容器名</param>
    public void DeleteBlob(string fileName, string mycontainer)
    {
        CloudBlockBlob blob = GetContainer(mycontainer, fileName);
        blob.Delete();
    }
    #endregion
}
View Code

2).單元測試類:class AzureBlob_Test.cs函數

[TestClass]
public class AzureBlob_Test
{
    AzureBlob azureBlob = new AzureBlob();
    private string containername = ConfigurationManager.AppSettings["userimg"].ToString();

    [TestMethod]
    public void TestUploadToBlob()
    {
        //string imgCode = ""

        //Byte[] buffer = Convert.FromBase64String(imgCode.Replace(" ", "+"));
        //var result = azureBlob.UploadToBlob("test", containername, buffer);

        string str = "userImg/430223198701159158_601421613.png";
        var str1 = str.Contains("/");

        Assert.IsTrue(str1);
    }

    [TestMethod] //OK
    public void TestGetBlobURI() 
    {
        var result = azureBlob.GetBlobURI("test", containername);
        Assert.IsNotNull(result);//https://08afc0c4store.blob.core.chinacloudapi.cn/images/test
    }

    [TestMethod] //OK
    public void TestUploadToBlob2()
    {
        var fileName = "1_2.jpg";
        var filePath = @"F:\img\"+ fileName;
        azureBlob.UploadToBlob(fileName, containername, filePath);
    }

    [TestMethod]
    public void TestDownloadToFile()
    {
        var fileName = "2017.jpg";
        var filePath = @"images\2017.jpg";
        //filePath = azureBlob.GetBlobURI(fileName, containername);
        azureBlob.DownloadToFile(fileName, containername, filePath);
    }

    [TestMethod]
    public void TestDownloadToStream()
    {
        var fileName = "2017.jpg";;
        //filePath = azureBlob.GetBlobURI(fileName, containername);
        azureBlob.DownloadToStream(fileName, containername);
    }

    [TestMethod]
    public void TestDownloadToFileStream()
    {
        var fileName = "2017.jpg"; ;
        var filePath = @"test\2017.jpg";
        //filePath = azureBlob.GetBlobURI(fileName, containername);
        azureBlob.DownloadToFileStream(fileName, containername, filePath);
    }

    [TestMethod] //OK
    public void TestDeleteBlob()
    {
        var fileName = "2017.jpg";
        azureBlob.DeleteBlob(fileName, containername);
    }
}
View Code

3).在web.config 下的<configuration>-><appSettings>下添加:

<!--存儲圖片鏈接字符串 -->
<add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=test;AccountKey=1234;EndpointSuffix=core.chinacloudapi.cn" />
<!--容器名,必須是小寫-->
<add key="test" value="test" />

4).經過Azure Storage Explorer 6查看上傳的圖片,下載地址爲:http://azurestorageexplorer.codeplex.com/releases/view/125870 下的 AzureStorageExplorer6Preview3.zip

5).圖片訪問路徑:https://(AccountName).blob.(EndpointSuffix)/ecgimg1/test.png

6).經過html轉pdf 微軟雲圖片的路徑(5))導出顯示不了,只能先下載到本地,導出pdf成功以後,刪除本地的圖片。

參考:http://www.jianshu.com/p/bf265c6ceedd

          https://docs.azure.cn/zh-cn/storage/storage-dotnet-how-to-use-blobs 

相關開發資源 https://docs.azure.cn/zh-cn/storage/         

對比C#上傳 

1. 圖片上傳類:

FileExtensions.cs

public class FileExtensions
{
    //    <!--圖片上傳路徑-->
    public static readonly string filePath = AppDomain.CurrentDomain.BaseDirectory + @"img\";

    /// <summary>
    /// 將數據寫入文件
    /// </summary>
    /// <param name="data"></param>
    /// <param name="url"></param>
    /// <returns></returns>
    public static void WriterBase64File(string data, string url)
    {
        var path = Path.Combine(filePath, url.Replace("/", "\\"));
        var dir = path.Substring(0, path.LastIndexOf("\\"));
        if (!Directory.Exists(dir))
        {
            Directory.CreateDirectory(dir);
        }

        if (File.Exists(path))
        {
            File.Delete(path);
        }

        Byte[] buffer = Convert.FromBase64String(data.Replace(" ", "+"));
        File.WriteAllBytes(path, buffer);
    }

    /// <summary>
    /// 將數據寫入文件
    /// </summary>
    /// <param name="data"></param>
    /// <param name="url"></param>
    /// <returns></returns>
    public static void WriterImgFile(Bitmap data, string url)
    {
        var path = Path.Combine(filePath, url.Replace("~/", "").Replace("/", "\\"));
        var dir = path.Substring(0, path.LastIndexOf("\\"));
        if (!Directory.Exists(dir))
        {
            Directory.CreateDirectory(dir);
        }

        if (File.Exists(path))
        {
            File.Delete(path);
        }

        data.Save(path);
    }

    /// <summary>
    /// 將數據寫入文件
    /// </summary>
    /// <param name="data"></param>
    /// <param name="url"></param>
    /// <returns></returns>
    public static void WriterBinaryFile(byte[] data, string url)
    {
        var path = Path.Combine(filePath, url.Replace("/", "\\"));
        var dir = path.Substring(0, path.LastIndexOf("\\"));
        if (!Directory.Exists(dir))
        {
            Directory.CreateDirectory(dir);
        }

        if (File.Exists(path))
        {
            File.Delete(path);
        }

        File.WriteAllBytes(path, data);
    }

    /// <summary>
    /// 圖片旋轉
    /// </summary>
    /// <param name="sm"></param>
    /// <param name="max"></param>
    /// <returns></returns>
    public static byte[] ResizeImageFile(Stream sm, int max = 1024)
    {
        Image original = Image.FromStream(sm);
        decimal ratio = (decimal)1.0;
        int targetW = original.Width;
        int targetH = original.Height;
        if (targetW <= max && targetH <= max)
        {
            return StreamToBytes(sm);
        }
        if (original.Height > original.Width)
        {
            ratio = (decimal)max / original.Height;
            targetH = 1024;
            targetW = (int)((decimal)targetW * ratio);
        }
        else
        {
            ratio = (decimal)max / original.Width;
            targetW = 1024;
            targetH = (int)((decimal)targetH * ratio);
        }

        Image imgPhoto = Image.FromStream(sm);
        // Create a new blank canvas.  The resized image will be drawn on this canvas.
        Bitmap bmPhoto = new Bitmap(targetW, targetH, PixelFormat.Format24bppRgb);
        bmPhoto.SetResolution(72, 72);
        Graphics grPhoto = Graphics.FromImage(bmPhoto);
        grPhoto.SmoothingMode = SmoothingMode.AntiAlias;
        grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
        grPhoto.PixelOffsetMode = PixelOffsetMode.HighQuality;
        grPhoto.DrawImage(imgPhoto, new Rectangle(0, 0, targetW, targetH), 0, 0, original.Width,
            original.Height, GraphicsUnit.Pixel);
        // Save out to memory and then to a file.  We dispose of all objects to make sure the files don't stay locked.
        MemoryStream mm = new MemoryStream();
        bmPhoto.Save(mm, ImageFormat.Jpeg);
        original.Dispose();
        imgPhoto.Dispose();
        bmPhoto.Dispose();
        grPhoto.Dispose();
        return mm.GetBuffer();
    }

    /// <summary>
    /// 根據圖片exif調整方向  
    /// </summary>
    /// <param name="byteArray"></param>
    /// <param name="orien">angle 1:逆時針90,2:逆時針180,3:逆時針270</param>
    /// <returns></returns>
    public static Bitmap RotateImage(byte[] byteArray, int orien)
    {
        MemoryStream sm = new MemoryStream(byteArray);
        Image img = Image.FromStream(sm);
        switch (orien)
        {
            case 1:
                img.RotateFlip(RotateFlipType.Rotate90FlipNone);
                break;
            case 2:
                img.RotateFlip(RotateFlipType.Rotate180FlipNone); //vertical flip  
                break;
            case 3:
                img.RotateFlip(RotateFlipType.Rotate270FlipNone);
                break;
            default:
                break;
        }
        return (Bitmap)img;
    }


    public static byte[] BitmapToBytes(Bitmap bitmap)
    {
        using (var ms = new MemoryStream())
        {
            bitmap.Save(ms, ImageFormat.Jpeg);
            var byteImage = ms.ToArray();
            return byteImage;
        }
    }


    public static byte[] StreamToBytes(Stream sm)
    {
        byte[] bytes = new byte[sm.Length];
        sm.Read(bytes,0, bytes.Length);
        //  設置當前流的位置爲流的開始
        sm.Seek(0,SeekOrigin.Begin);
        return bytes;
    }
   }
}
FileExtensions

調用:

//限定上傳圖片的格式類型
string[] LimitPictureType = { ".jpg", ".jpeg", ".gif", ".png", ".bmp" };
//當圖片上被選中時,拿到文件的擴展名
string currentPictureExtension = Path.GetExtension(file.FileName).ToLower();

//文件名稱
var fileName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + currentPictureExtension;

//圖片字節流
Byte[] fileData = new Byte[file.ContentLength]; //file 是 System.Web.HttpPostedFile;
using (var binaryReader = new BinaryReader(file.InputStream))
{
    fileData = binaryReader.ReadBytes(file.ContentLength);
}

//圖片上傳
FileExtensions.WriterBinaryFile(fileData, fileName);


 //圖片字節流
Byte[] fileData = FileExtensions.ResizeImageFile(file.InputStream);


// angle 1:逆時針90,2:逆時針180,3:逆時針270
using (var img = FileExtensions.RotateImage(fileData, angle))
{
    fileData = FileExtensions.BitmapToBytes(img);
    AzureBlob.UploadToBlob(fileName, containname, fileData);
}

 2.C#獲取某站點下的圖片文件二進制字節流

#region 獲取圖片的二進制流
/// <summary>
/// 獲取圖片的二進制流
/// </summary>
/// <param name="path">h5上保存路邊的具體地址(好比:http://10.2.29.176:8082/img/20180320.jpg )</param>
/// <returns></returns>
private static byte[] GetfileData(string path)
{
    WebRequest myrequest = WebRequest.Create(path);
    WebResponse myresponse = myrequest.GetResponse();
    Stream imgstream = myresponse.GetResponseStream();
    Image img = Image.FromStream(imgstream);
    MemoryStream ms = new MemoryStream();
    img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
    var fileData = ms.ToArray();
    return fileData;
}
#endregion

 3. Http上傳文件 

#region Http上傳文件
/// <summary>
/// Http上傳文件
/// </summary> 
/// <param name="url">url</param>
/// <param name="contentType">類型:multipart/form-data</param>
/// <param name="fileName">文件名稱</param>
/// <param name="bArr">文件二進制字節流</param>
/// <param name="uploadfilename">input type='file' 對應的name</param>
/// <returns></returns>
public static string HttpUploadFile(string url,string contentType,string fileName,byte[] bArr,string uploadfilename)
{
    // 設置參數
    HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
    CookieContainer cookieContainer = new CookieContainer();
    request.CookieContainer = cookieContainer;
    request.AllowAutoRedirect = true;
    request.Method = "POST";
    string boundary = DateTime.Now.Ticks.ToString("X"); // 隨機分隔線
    request.ContentType = string.Format("{0};charset=utf-8;boundary={1}", contentType, boundary);
    byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
    byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");

    //請求頭部信息 
    StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"{0}\";filename=\"{1}\"\r\nContent-Type:application/octet-stream\r\n\r\n", uploadfilename, fileName));
    byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString());

    Stream postStream = request.GetRequestStream();
    postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
    postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
    postStream.Write(bArr, 0, bArr.Length);
    postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
    postStream.Close();

    //發送請求並獲取相應迴應數據
    HttpWebResponse response = request.GetResponse() as HttpWebResponse;
    //直到request.GetResponse()程序纔開始向目標網頁發送Post請求
    Stream instream = response.GetResponseStream();
    StreamReader sr = new StreamReader(instream, Encoding.UTF8);
    //返回結果網頁(html)代碼
    string content = sr.ReadToEnd();
    return content;
}
#endregion

調用:HttpUploadFile(‘具體的url’, "multipart/form-data", fileName, fileData, "uploadfile1");

注意:uploadfile 爲<input type="file" name="uploadfile1" style="font-size:14px"> 中 name的值

對應的form表單爲:

<form enctype="multipart/form-data" action="/upload" method="post">
    <input type="file" name="uploadfile1" style="font-size:14px">
    <input type="submit" value="upload" style="font-size:14px">
</form>
相關文章
相關標籤/搜索