The Azure SDK for Go team at Microsoft is excited to announce the stable release of the Azure Files client library for Go. Azure Files offers fully managed file shares in the cloud that are accessible via the industry standard Server Message Block (SMB) protocol. Azure Files shares can be mounted concurrently by cloud or on-premises deployments of Windows, Linux, and macOS. Azure Files shares can also be cached on Windows Servers with Azure File Sync for fast access near where the data is being used.
To upgrade from the legacy Azure Files library for Go, see the migration guide.
Install the package
The Azure Files client library is named azfile
. To install the latest version of azfile
, use the following go get
command:
go get github.com/Azure/azure-sdk-for-go/sdk/storage/azfile
We assume that you have:
- An Azure subscription.
- A working development environment for Go version 1.18 or above.
Create a client
Client
is a type that exposes methods that invoke service operations. A Client
type is shareable between multiple goroutines simultaneously and safely.
Azure Files offers four types of resources: the storage account, the shares within the account, and the directories and files within a share. Instances of the service.Client
, share.Client
, directory.Client
, and file.Client
types provide methods to manipulate shares, directories, and files within a storage account. You must specify the storage account when you create a client.
You can create a client using an Azure Files connection string or access key or with a Shared Access Signature(SAS) (obtained via the Azure portal).
Use Azure Files connection string
Azure Files supports authentication using a connection string, which you can get from the Azure portal.
package main
import "github.com/Azure/azure-sdk-for-go/sdk/storage/azfile/service"
func main() {
serviceClient, err := service.NewClientFromConnectionString("<Azure Storage Connection String>", nil)
if err != nil {
//TODO: handle error
panic(err)
}
}
Use the SharedKeyCredential
Azure Files supports authentication using access key, which you can get from the Azure portal.
package main
import "github.com/Azure/azure-sdk-for-go/sdk/storage/azfile/service"
func main() {
// create a credential for authenticating using shared key
cred, err := service.NewSharedKeyCredential("<my-storage-account-name>", "<my-storage-account-key>")
if err != nil {
//TODO: handle error
panic(err)
}
// create service.Client for the specified storage account that uses the above credential
serviceClient, err := service.NewClientWithSharedKeyCredential("https://<my-storage-account-name>.file.core.windows.net/", cred, nil)
if err != nil {
//TODO: handle error
panic(err)
}
}
Use the Shared Access Signature (SAS) token
Azure Files supports authentication using SAS token, which you can get from the Azure portal.
package main
import "github.com/Azure/azure-sdk-for-go/sdk/storage/azfile/service"
func main() {
serviceClient, err := service.NewClientWithNoCredential("https://<my-storage-account-name>.file.core.windows.net/?<sas token>", nil)
if err != nil {
//TODO: handle error
panic(err)
}
}
Share operations
The share.Client
type exposes share operations that manipulate the lifecycle of the Azure Files share.
Create a share
The share
package’s Create
method creates a new share under the specified account. If a share with the same name already exists, the method call raises a ResourceAlreadyExists
error.
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azfile/share"
)
func handleError(err error) {
if err != nil {
log.Fatal(err.Error())
}
}
func main() {
accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
if !ok {
panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
}
accountKey, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_KEY")
if !ok {
panic("AZURE_STORAGE_ACCOUNT_KEY could not be found")
}
shareName := "testshare"
shareURL := fmt.Sprintf("https://%s.file.core.windows.net/%s", accountName, shareName)
cred, err := share.NewSharedKeyCredential(accountName, accountKey)
handleError(err)
shareClient, err := share.NewClientWithSharedKeyCredential(shareURL, cred, nil)
handleError(err)
_, err = shareClient.Create(context.TODO(), nil)
handleError(err)
}
Delete a share
The share
package’s Delete
method is a share lifecycle method that marks the specified share for deletion. During garbage collection, Azure deletes the share and any directories/files within it. If the share is missing, the method call raises a ResourceNotFound
error.
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azfile/share"
)
func handleError(err error) {
if err != nil {
log.Fatal(err.Error())
}
}
func main() {
accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
if !ok {
panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
}
accountKey, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_KEY")
if !ok {
panic("AZURE_STORAGE_ACCOUNT_KEY could not be found")
}
shareName := "testshare"
shareURL := fmt.Sprintf("https://%s.file.core.windows.net/%s", accountName, shareName)
cred, err := share.NewSharedKeyCredential(accountName, accountKey)
handleError(err)
shareClient, err := share.NewClientWithSharedKeyCredential(shareURL, cred, nil)
handleError(err)
_, err = shareClient.Delete(context.TODO(), nil)
handleError(err)
}
Directory operations
The directory.Client
type exposes operations that can be performed on directories in a file share.
Create a directory
The directory
package’s Create
method creates a new directory under the specified share. If a directory with the same name already exists, the method call raises a ResourceAlreadyExists
error.
package main
import (
"context"
"log"
"os"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azfile/directory"
)
func handleError(err error) {
if err != nil {
log.Fatal(err.Error())
}
}
func main() {
connectionString, ok := os.LookupEnv("AZURE_STORAGE_CONNECTION_STRING")
if !ok {
panic("AZURE_STORAGE_CONNECTION_STRING could not be found")
}
shareName := "testShare"
dirName := "testDirectory"
dirClient, err := directory.NewClientFromConnectionString(connectionString, shareName, dirName, nil)
handleError(err)
_, err = dirClient.Create(context.Background(), nil)
handleError(err)
}
Delete a directory
The directory
package’s Delete
method deletes the specified empty directory. If you attempt to delete directories that aren’t empty, the method call raises a DirectoryNotEmpty
error. If the directory is missing, the method call raises a ResourceNotFound
error.
package main
import (
"context"
"log"
"os"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azfile/directory"
)
func handleError(err error) {
if err != nil {
log.Fatal(err.Error())
}
}
func main() {
connectionString, ok := os.LookupEnv("AZURE_STORAGE_CONNECTION_STRING")
if !ok {
panic("AZURE_STORAGE_CONNECTION_STRING could not be found")
}
shareName := "testShare"
dirName := "testDirectory"
dirClient, err := directory.NewClientFromConnectionString(connectionString, shareName, dirName, nil)
handleError(err)
_, err = dirClient.Delete(context.Background(), nil)
handleError(err)
}
File operations
The file.Client
type exposes the operations that interact with the files that reside inside the Azure Files share or directory.
Upload file to a directory
The UploadFile
method uploads a file in chunks to a file inside the Azure Files share or directory. This operation can be performed on an existing file only, otherwise it raises a ResourceNotFound
error.
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azfile/file"
)
func handleError(err error) {
if err != nil {
log.Fatal(err.Error())
}
}
func main() {
// Set up file to upload
fileSize := 8 * 1024 * 1024
fileName := "test_upload_file.txt"
fileData := make([]byte, fileSize)
err := os.WriteFile(fileName, fileData, 0666)
handleError(err)
// Open the file to upload
fileHandler, err := os.Open(fileName)
handleError(err)
// delete the local file if required.
defer func(name string) {
err = os.Remove(name)
handleError(err)
}(fileName)
// close the file after it is no longer required.
defer func(fh *os.File) {
err = fh.Close()
handleError(err)
}(fileHandler)
accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
if !ok {
panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
}
accountKey, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_KEY")
if !ok {
panic("AZURE_STORAGE_ACCOUNT_KEY could not be found")
}
cred, err := file.NewSharedKeyCredential(accountName, accountKey)
handleError(err)
shareName := "testShare"
dirName := "testDirectory"
fileURL := fmt.Sprintf("https://%s.file.core.windows.net/%s/%s/%s", accountName, shareName, dirName, fileName)
fileClient, err := file.NewClientWithSharedKeyCredential(fileURL, cred, nil)
handleError(err)
_, err = fileClient.Create(context.Background(), int64(fileSize), nil)
handleError(err)
err = fileClient.UploadFile(context.Background(), fileHandler, nil)
handleError(err)
}
Download file from a directory
DownloadFile
downloads a file from the Azure Files share or directory to a local file that is passed as a parameter. If the size doesn’t match, the method truncates the destination file.
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azfile/file"
)
func handleError(err error) {
if err != nil {
log.Fatal(err.Error())
}
}
func main() {
// Set up file to download to
destFileName := "test_download_file.txt"
destFile, err := os.Create(destFileName)
handleError(err)
defer func(destFile *os.File) {
err = destFile.Close()
handleError(err)
}(destFile)
accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
if !ok {
panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
}
accountKey, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_KEY")
if !ok {
panic("AZURE_STORAGE_ACCOUNT_KEY could not be found")
}
cred, err := file.NewSharedKeyCredential(accountName, accountKey)
handleError(err)
shareName := "testShare"
dirName := "testDirectory"
fileURL := fmt.Sprintf("https://%s.file.core.windows.net/%s/%s/%s", accountName, shareName, dirName, destFileName)
fileClient, err := file.NewClientWithSharedKeyCredential(fileURL, cred, nil)
handleError(err)
_, err = fileClient.DownloadFile(context.Background(), destFile, nil)
handleError(err)
}
Delete file in a directory
The file
package’s Delete
method immediately removes the file from the storage account. For more information, see the delete file documentation.
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azfile/file"
)
func handleError(err error) {
if err != nil {
log.Fatal(err.Error())
}
}
func main() {
accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
if !ok {
panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
}
accountKey, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_KEY")
if !ok {
panic("AZURE_STORAGE_ACCOUNT_KEY could not be found")
}
cred, err := file.NewSharedKeyCredential(accountName, accountKey)
handleError(err)
shareName := "testShare"
dirName := "testDirectory"
fileName := "testFile"
fileURL := fmt.Sprintf("https://%s.file.core.windows.net/%s/%s/%s", accountName, shareName, dirName, fileName)
fileClient, err := file.NewClientWithSharedKeyCredential(fileURL, cred, nil)
handleError(err)
_, err = fileClient.Delete(context.Background(), nil)
handleError(err)
}
Summary
The Azure Files library for Go allows users to manipulate files, directories and shares in Azure Storage. To learn more, see our documentation. You can also find more examples either on pkg.go.dev or in our GitHub repository.
Feedback
We’d love to hear about your experiences using the Azure SDK for Go. Send us your feedback on our Slack Channel or at the #golang-friends channel on the Microsoft Open Source Discord Server.
For feature requests, bug reports, or general support, open an issue in the Azure SDK for Go repository on GitHub.
0 comments