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のバージョンに依存する形になる。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です