Azure.Storage.Blobsを使用したファイル操作
前提
Blobsを使用したファイルの操作の仕方がわからない人。ドキュメントがほどんど英語で、日本語での解説がやたらと少なくて困っている人。AzureBlobの使用を検討している人向け。
実際に、自身でも感じたが、Blobのファイル操作の情報は古くて使い物にならないのがほとんどだった。インターネットの難しいところだが、古い情報も新しい情報も関係なく検索に引っかかってくる。最もヒットしやすい情報を信じてBlobのモジュールを組み込むと、サポート外になるので注意してほしい。ちなみに、こちらの情報もいずれ「サポート外(※1)」になると思うので、その辺はご留意いただきたい。
※1 Azure.Storage.Blobs 12.9.0を使用している
まずは適当にクラスを作成。Blobsをインポートした。VBを使用しているのは手抜きではない。。
Imports Azure.Storage.Blobs
Imports Azure.Storage.Blobs.Models
Public Class Blob
End Class
削除とアップロード
やり方さえわかれば、さほど難しい話でもないので下記ソースを参照してほしい。
Public Sub Upload(ByVal fileName As String, ByVal uploadFile As HttpPostedFile)
'コンテナー名
Dim container As BlobContainerClient = New BlobContainerClient("接続文字列", "コンテナー名")
'クライアント作成
Dim client As BlobClient = container.GetBlobClient(fileName)
'すでにファイルがある場合は削除する
If client.Exists Then
client.Delete()
End If
'ファイルをアップロード
client.Upload(uploadFile.InputStream)
End Sub
上書きという考え方がないので、ファイルの存在チェックをしてからアップロードを行う必要がある。
ほかにも注意をする必要があるとすれば、Existsでサーバーに一度通信を行わなければならないので、繰り返し処理を行うと「非常に遅い」という点だろうか。このメソッドはフロントサイドで使用されることはほとんどないと思うのでエンドユーザーへの影響は小さいと思うが、バックエンドで使用するユーザーに対しては注意喚起が必要になるかもしれない。
大量データのアップロードが必要な場合は、非同期での実装をお勧めしたい。
ファイルをコピー
Public Sub Copy(sourceFileName As String, ByVal destFileName As String)
'コンテナー名
Dim container As BlobContainerClient = New BlobContainerClient("接続文字列", "コンテナー名")
'コピー元のクライアント作成
Dim source As BlobClient = container.GetBlobClient(sourceFileName)
'コピー先のクライアント作成
Dim dest As BlobClient = container.GetBlobClient(destFileName)
'すでにファイルがある場合は削除する
If dest.Exists Then
dest.Delete()
End If
'元ファイルがあればコピーする
If source.Exists Then
dest.StartCopyFromUri(source.Uri)
End If
End Sub
Existsが2回走っているので、少々重たい。
元ファイルがあることを前提にできるような仕組みにして一度の通信にしたほうが良いと思う。
ディレクトリーをコピー
調べた限りだと、ディレクトリを丸ごとコピーするような機能は提供されていないようだった。そのため、自力でディレクトリリストを作ってファイルをコピーしてやる必要がある。
基本的にファイルのコピーと一緒なので、ループの仕方だけ。
Public Sub DirectoryCopy(ByVal directoryPath As String, ByVal destPath As String)
'コンテナー名
Dim container As BlobContainerClient = New BlobContainerClient("接続文字列", "コンテナー名")
'ページでループ
For Each item As Azure.Page(Of BlobItem) In container.GetBlobs.AsPages
'ページ内のファイル単位でループ
For Each item2 As BlobItem In item.Values
'パス形式になっているので、ディレクトリに一致するものを探している。
If item2.Name.IndexOf(directoryPath) > -1 Then
'コピー先のディレクトリ名と、Blob内のファイル名で新しいファイルのクライアントを作っている
Dim client As BlobClient = container.GetBlobClient(destPath & IO.Path.GetFileName(item2.Name))
'あとは一緒なので略
End If
Next
Next
End Sub
UIでのファイル操作と同じような形で実装してみた。ページをめくって該当のディレクトリに到達したら、上から順にコピーしていくようなイメージだ。
ダウンロード
ダウンロード、というと少々大げさだ。BlobなのでUrlを指定すればいいだけのことだ。勝手にブラウザがgetしてきてくれる。
存在チェックを入れたいなどの理由があって、あえて書くなら以下のような感じか。
Public Function View(ByVal fileName As String) As String
'コンテナー名
Dim container As BlobContainerClient = New BlobContainerClient("接続文字列", "コンテナー名")
'クライアント作成
Dim client As BlobClient = container.GetBlobClient(fileName)
'ファイルがある場合はパスを返す
If client.Exists Then
Return client.Uri.ToString
End If
Return String.Empty
End Function
まとめ
今回のサンプルは普遍的なものではないので十分に注意をしたうえで参考にしてもらいたい。当然のこと、Azure.Storage.Blobsのバージョンに依存する形になる。
コメントを残す