Azureストレージ上にあるBlockBlobをFTPで転送する方法
Azureの開発をしていて、BlockBlobをFTPでサーバーへ転送する必要があったので、覚書をして残しておきます。
ZIPファイル化(Azureのストレージ上にあるBLOBをzipして保存する方法)と同様にローカルにあるファイルのように直接転送することが出来ません。
ZIPファイル化と同じように、一度ストリームに読み込む必要があります。
以下サンプルコードです。(今回はFTPS送信のため、証明書のチェックがあります)
[code]using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Blob; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks;namespace WorkerRole1 { class Class1 { public void TransferFile_FTP() { //FTPサーバーの指定 // ServerNameを指定する string ServerName = “ftp://hogehoge.com/”; // FTPのユーザー名 string FtpUsername = “UserName”; // FTPのパスワード string FtpPassword = “Password”; // ユーザー名とパスワードを指定 NetworkCredential cred = new NetworkCredential(FtpUsername, FtpPassword);//Blobコンテナーの指定 // ストレージアカウントの生成(StorageConnectionStringはapp.configに記載、内容はポータルから取得する) /* <appSettings> <add key=”StorageConnectionString” value=”DefaultEndpointsProtocol=https;AccountName=account-name;AccountKey=account-key” /> </appSettings> */ CloudStorageAccount storageAccount = CloudStorageAccount.Parse(StorageConnectionString); // BLOBクライアントの生成 CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); // BLOBのコンテナ取得 CloudBlobContainer container = blobClient.GetContainerReference(“コンテナ名'”); // Blobコンテナーからファイル名を取得する。 // ファイル名を指定して転送する場合には、nullをファイル名(仮想階層込)にする。 // またファイル名は一部のみでもよい。 foreach (IListBlobItem item in container.ListBlobs(null, false)) { //BlockBlobの場合に転送する。(ここをCloudAppendBlobに返るとAppendBlobも転送できる) if (item.GetType() == typeof(CloudBlockBlob)) { //item指定 CloudBlockBlob blob = (CloudBlockBlob)item; //Ftpサーバーの指定 // ファイル名の指定 // 仮想階層を使用している場合には、仮想階層をReplaceで除く string FileNames = blob.Name; //blob.Name.Replace(“仮想階層”, “”); // FtpWebRequestの作成 Uri u = new Uri(ServerName + FileNames); FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(u); //ログインユーザー名とパスワードを設定 ftpReq.Credentials = cred; // Methodには”STOR”を設定 ftpReq.Method = WebRequestMethods.Ftp.UploadFile; // 接続高速化 ftpReq.Proxy = null; // 要求の完了後に接続を閉じる ftpReq.KeepAlive = false; // ASCIIモードで転送する ftpReq.UseBinary = false; // PASSIVEモードを有効にする ftpReq.UsePassive = true; // SSL通信設定 ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(OnRemoteCertificateValidationCallback); ftpReq.EnableSsl = true; // ファイルをアップロードするためのStreamを取得 System.IO.Stream reqStrm = ftpReq.GetRequestStream(); CloudBlob ZipBlob = container.GetBlobReference(blob.Name); var memoryStream = new MemoryStream(); ZipBlob.DownloadToStream(memoryStream); // BLOBを一度ストリームに取り込み、サイズを取得する string text = Encoding.UTF8.GetString(memoryStream.ToArray()); // ファイルを読み込むバイト配列の初期化 long fileByteLength = ZipBlob.Properties.Length; byte[] fileBytes = new byte[fileByteLength]; // バイト配列に読み込む ZipBlob.DownloadToByteArray(fileBytes, 0); //アップロードのためのstreamに書き込み int fileByteLengths = (int)fileByteLength; reqStrm.Write(fileBytes, 0, fileByteLengths); //クローズ reqStrm.Close(); // FtpWebResponseを取得 FtpWebResponse ftpRes = (FtpWebResponse)ftpReq.GetResponse(); } } } private static bool OnRemoteCertificateValidationCallback( Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { //証明の内容をチェック if (sslPolicyErrors == SslPolicyErrors.None) { //SSL証明書に問題なし return true; } else { if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors) { //【SSL証明書】ChainStatusが、空でない配列を返しました return false; } else if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch) { //【ERROR】証明書の名前が一致していません return false; } else if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable) { //【SSL証明書】証明書が利用できません return false; } else { //【SSL証明書】予期しないエラーが発生しました return false; } } } } } [/code] |