Microsoft Azure client library for Blob Storage - Azure Blob Storage is Microsoft's object storage solution for the cloud, optimized for storing massive amounts of unstructured data such as text or binary data.
—
Container clients provide comprehensive functionality for managing blob containers, including creation, configuration, blob management, and access control.
The synchronous client for blob container operations.
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobContainerClientBuilder;
import com.azure.storage.blob.BlobServiceClient;
// From service client (recommended)
BlobServiceClient serviceClient = new BlobServiceClientBuilder()
.connectionString("DefaultEndpointsProtocol=https;AccountName=myaccount;...")
.buildClient();
BlobContainerClient containerClient = serviceClient.getBlobContainerClient("mycontainer");
// Direct creation using builder
BlobContainerClient containerClient = new BlobContainerClientBuilder()
.connectionString("DefaultEndpointsProtocol=https;AccountName=myaccount;...")
.containerName("mycontainer")
.buildClient();
// Using endpoint and credential
BlobContainerClient containerClient = new BlobContainerClientBuilder()
.endpoint("https://myaccount.blob.core.windows.net/mycontainer")
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();import com.azure.storage.blob.models.*;
import com.azure.core.http.rest.Response;
import com.azure.core.util.Context;
// Create container
containerClient.create();
// Create with options and metadata
Map<String, String> metadata = Map.of(
"environment", "production",
"team", "backend",
"created-by", "deployment-script"
);
BlobContainerCreateOptions createOptions = new BlobContainerCreateOptions()
.setMetadata(metadata)
.setPublicAccessType(PublicAccessType.BLOB);
Response<Void> createResponse = containerClient.createWithResponse(
createOptions,
Duration.ofSeconds(30),
Context.NONE
);
System.out.println("Container created, status: " + createResponse.getStatusCode());
// Create if not exists
boolean created = containerClient.createIfNotExists();
if (created) {
System.out.println("Container was created");
} else {
System.out.println("Container already exists");
}
// Check if container exists
Boolean exists = containerClient.exists();
System.out.println("Container exists: " + exists);
// Delete container
containerClient.delete();
// Delete with conditions
BlobRequestConditions conditions = new BlobRequestConditions()
.setIfUnmodifiedSince(OffsetDateTime.now().minusDays(1));
Response<Void> deleteResponse = containerClient.deleteWithResponse(
conditions,
Duration.ofSeconds(30),
Context.NONE
);
// Delete if exists
boolean deleted = containerClient.deleteIfExists();// Get container properties
BlobContainerProperties properties = containerClient.getProperties();
System.out.println("Last modified: " + properties.getLastModified());
System.out.println("ETag: " + properties.getETag());
System.out.println("Public access: " + properties.getPublicAccess());
System.out.println("Lease status: " + properties.getLeaseStatus());
System.out.println("Lease state: " + properties.getLeaseState());
System.out.println("Has immutability policy: " + properties.hasImmutabilityPolicy());
System.out.println("Has legal hold: " + properties.hasLegalHold());
System.out.println("Metadata: " + properties.getMetadata());
// Set metadata
Map<String, String> newMetadata = Map.of(
"environment", "staging",
"version", "2.0",
"last-updated", OffsetDateTime.now().toString()
);
containerClient.setMetadata(newMetadata);
// Set metadata with conditions
BlobRequestConditions metadataConditions = new BlobRequestConditions()
.setIfMatch(properties.getETag());
Response<Void> metadataResponse = containerClient.setMetadataWithResponse(
newMetadata,
metadataConditions,
Duration.ofSeconds(30),
Context.NONE
);import com.azure.storage.blob.models.*;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.ArrayList;
// Get current access policy
BlobContainerAccessPolicies accessPolicies = containerClient.getAccessPolicy();
System.out.println("Public access: " + accessPolicies.getBlobAccessType());
for (BlobSignedIdentifier identifier : accessPolicies.getIdentifiers()) {
System.out.println("Policy ID: " + identifier.getId());
BlobAccessPolicy policy = identifier.getAccessPolicy();
System.out.println("Permissions: " + policy.getPermissions());
System.out.println("Start time: " + policy.getStartsOn());
System.out.println("Expiry time: " + policy.getExpiresOn());
}
// Set access policy with stored access policies
List<BlobSignedIdentifier> identifiers = new ArrayList<>();
BlobSignedIdentifier readOnlyPolicy = new BlobSignedIdentifier()
.setId("ReadOnlyAccess")
.setAccessPolicy(new BlobAccessPolicy()
.setPermissions("r")
.setStartsOn(OffsetDateTime.now())
.setExpiresOn(OffsetDateTime.now().plusDays(30)));
BlobSignedIdentifier fullAccessPolicy = new BlobSignedIdentifier()
.setId("FullAccess")
.setAccessPolicy(new BlobAccessPolicy()
.setPermissions("racwdl")
.setStartsOn(OffsetDateTime.now())
.setExpiresOn(OffsetDateTime.now().plusDays(7)));
identifiers.add(readOnlyPolicy);
identifiers.add(fullAccessPolicy);
// Apply access policies
containerClient.setAccessPolicy(PublicAccessType.CONTAINER, identifiers);
// Remove public access
containerClient.setAccessPolicy(null, identifiers);// Get blob client
BlobClient blobClient = containerClient.getBlobClient("myfile.txt");
// Create blob client with snapshot
BlobClient snapshotClient = containerClient.getBlobClient("myfile.txt", "2023-12-01T10:30:00.1234567Z");
// Check if blob exists
boolean blobExists = blobClient.exists();
// Upload a simple blob
String content = "Hello, Azure Blob Storage!";
blobClient.upload(BinaryData.fromString(content), true); // overwrite if exists
// Upload with metadata and properties
Map<String, String> blobMetadata = Map.of("author", "system", "type", "log");
BlobHttpHeaders headers = new BlobHttpHeaders()
.setContentType("text/plain")
.setContentEncoding("utf-8")
.setCacheControl("no-cache");
BlobUploadFromFileOptions uploadOptions = new BlobUploadFromFileOptions("local-file.txt")
.setHeaders(headers)
.setMetadata(blobMetadata)
.setTags(Map.of("environment", "prod", "team", "backend"))
.setTier(AccessTier.HOT);
Response<BlockBlobItem> uploadResponse = blobClient.uploadFromFileWithResponse(
uploadOptions,
Duration.ofMinutes(5),
Context.NONE
);import com.azure.core.http.rest.PagedIterable;
// List all blobs
PagedIterable<BlobItem> blobs = containerClient.listBlobs();
for (BlobItem blob : blobs) {
System.out.println("Blob: " + blob.getName());
System.out.println("Size: " + blob.getProperties().getContentLength() + " bytes");
System.out.println("Type: " + blob.getProperties().getBlobType());
System.out.println("Last Modified: " + blob.getProperties().getLastModified());
System.out.println("Access Tier: " + blob.getProperties().getAccessTier());
}
// List with options and filtering
ListBlobsOptions listOptions = new ListBlobsOptions()
.setPrefix("logs/2023/")
.setMaxResultsPerPage(100)
.setDetails(new BlobListDetails()
.setRetrieveDeletedBlobs(true)
.setRetrieveMetadata(true)
.setRetrieveTags(true)
.setRetrieveSnapshots(true)
.setRetrieveVersions(true)
.setRetrieveUncommittedBlobs(false));
PagedIterable<BlobItem> filteredBlobs = containerClient.listBlobs(listOptions, Duration.ofMinutes(2));
for (BlobItem blob : filteredBlobs) {
System.out.println("Blob: " + blob.getName());
System.out.println("Metadata: " + blob.getMetadata());
System.out.println("Tags: " + blob.getTags());
System.out.println("Is deleted: " + blob.isDeleted());
System.out.println("Is current version: " + blob.isCurrentVersion());
if (blob.getSnapshot() != null) {
System.out.println("Snapshot: " + blob.getSnapshot());
}
}
// Hierarchical listing (simulating folders)
String delimiter = "/";
PagedIterable<BlobItem> hierarchicalBlobs = containerClient.listBlobsByHierarchy(delimiter);
for (BlobItem item : hierarchicalBlobs) {
if (item.isPrefix()) {
System.out.println("Directory: " + item.getName());
} else {
System.out.println("File: " + item.getName());
}
}
// List with prefix and hierarchy
ListBlobsOptions hierarchicalOptions = new ListBlobsOptions()
.setPrefix("documents/2023/");
PagedIterable<BlobItem> folderBlobs = containerClient.listBlobsByHierarchy(
delimiter,
hierarchicalOptions,
Duration.ofMinutes(1)
);// Find blobs in container using tag queries
String tagFilter = "environment='production' AND team='backend'";
PagedIterable<TaggedBlobItem> taggedBlobs = containerClient.findBlobsByTags(tagFilter);
for (TaggedBlobItem taggedBlob : taggedBlobs) {
System.out.println("Blob: " + taggedBlob.getName());
System.out.println("Tags: " + taggedBlob.getTags().toMap());
}
// Find with options
FindBlobsOptions findOptions = new FindBlobsOptions(tagFilter)
.setMaxResultsPerPage(50);
PagedIterable<TaggedBlobItem> pagedTaggedBlobs = containerClient.findBlobsByTags(
findOptions,
Duration.ofSeconds(30)
);import com.azure.storage.blob.sas.*;
import java.time.OffsetDateTime;
// Generate container-level SAS token
OffsetDateTime expiryTime = OffsetDateTime.now().plusHours(2);
BlobContainerSasPermission permission = new BlobContainerSasPermission()
.setReadPermission(true)
.setListPermission(true)
.setAddPermission(true)
.setCreatePermission(true);
BlobServiceSasSignatureValues sasValues = new BlobServiceSasSignatureValues(expiryTime, permission)
.setStartTime(OffsetDateTime.now())
.setProtocol(SasProtocol.HTTPS_ONLY)
.setSasIpRange(SasIpRange.parse("192.168.1.0/24"));
String containerSas = containerClient.generateSas(sasValues);
System.out.println("Container SAS: " + containerSas);
// Generate SAS with stored access policy
BlobServiceSasSignatureValues storedPolicySas = new BlobServiceSasSignatureValues()
.setIdentifier("ReadOnlyAccess"); // Reference to stored policy
String storedPolicySasToken = containerClient.generateSas(storedPolicySas);The asynchronous client for blob container operations using reactive programming.
import com.azure.storage.blob.BlobContainerAsyncClient;
import reactor.core.publisher.Mono;
import reactor.core.publisher.Flux;
// From async service client
BlobServiceAsyncClient asyncServiceClient = new BlobServiceClientBuilder()
.connectionString("DefaultEndpointsProtocol=https;AccountName=myaccount;...")
.buildAsyncClient();
BlobContainerAsyncClient asyncContainerClient = asyncServiceClient.getBlobContainerAsyncClient("mycontainer");
// Direct creation
BlobContainerAsyncClient asyncContainerClient = new BlobContainerClientBuilder()
.connectionString("DefaultEndpointsProtocol=https;AccountName=myaccount;...")
.containerName("mycontainer")
.buildAsyncClient();// Create container asynchronously
Mono<Void> createMono = asyncContainerClient.create();
createMono
.doOnSuccess(v -> System.out.println("Container created successfully"))
.doOnError(ex -> System.err.println("Container creation failed: " + ex.getMessage()))
.subscribe();
// Chain operations
asyncContainerClient.createIfNotExists()
.filter(created -> created) // Only proceed if container was actually created
.flatMap(created -> {
Map<String, String> metadata = Map.of("created-time", OffsetDateTime.now().toString());
return asyncContainerClient.setMetadata(metadata);
})
.doOnSuccess(v -> System.out.println("Container created and metadata set"))
.subscribe();
// Get properties asynchronously
Mono<BlobContainerProperties> propertiesMono = asyncContainerClient.getProperties();
propertiesMono
.doOnNext(props -> {
System.out.println("Container last modified: " + props.getLastModified());
System.out.println("Public access: " + props.getPublicAccess());
System.out.println("Metadata count: " + props.getMetadata().size());
})
.subscribe();// List blobs asynchronously
Flux<BlobItem> blobFlux = asyncContainerClient.listBlobs();
blobFlux
.take(50) // Limit to first 50 blobs
.doOnNext(blob -> System.out.println("Blob: " + blob.getName() +
" (" + blob.getProperties().getContentLength() + " bytes)"))
.doOnComplete(() -> System.out.println("Listing complete"))
.doOnError(ex -> System.err.println("Listing failed: " + ex.getMessage()))
.subscribe();
// List with filtering
ListBlobsOptions listOptions = new ListBlobsOptions()
.setPrefix("images/")
.setMaxResultsPerPage(25);
Flux<BlobItem> filteredBlobFlux = asyncContainerClient.listBlobs(listOptions);
// Process blobs in parallel
filteredBlobFlux
.flatMap(blob -> {
BlobAsyncClient blobAsyncClient = asyncContainerClient.getBlobAsyncClient(blob.getName());
return blobAsyncClient.getProperties()
.map(props -> blob.getName() + " - " + props.getContentType());
}, 5) // Max 5 concurrent operations
.doOnNext(info -> System.out.println(info))
.subscribe();import com.azure.storage.blob.models.BlobStorageException;
// Comprehensive error handling
asyncContainerClient.create()
.doOnSuccess(v -> System.out.println("Container created"))
.onErrorResume(BlobStorageException.class, ex -> {
if (ex.getErrorCode() == BlobErrorCode.CONTAINER_ALREADY_EXISTS) {
System.out.println("Container already exists, continuing...");
return Mono.empty();
} else {
System.err.println("Storage error: " + ex.getErrorCode() + " - " + ex.getMessage());
return Mono.error(ex);
}
})
.onErrorResume(Exception.class, ex -> {
System.err.println("Unexpected error: " + ex.getMessage());
return Mono.error(new RuntimeException("Container creation failed", ex));
})
.subscribe();
// Retry operations
asyncContainerClient.getProperties()
.retry(3) // Retry up to 3 times on any error
.doOnNext(props -> System.out.println("Properties retrieved: " + props.getETag()))
.doOnError(ex -> System.err.println("Failed after retries: " + ex.getMessage()))
.subscribe();import com.azure.storage.blob.specialized.BlobLeaseClient;
import com.azure.storage.blob.specialized.BlobLeaseClientBuilder;
// Create lease client for container
BlobLeaseClient leaseClient = new BlobLeaseClientBuilder()
.containerClient(containerClient)
.buildClient();
// Acquire lease
String proposedLeaseId = UUID.randomUUID().toString();
String leaseId = leaseClient.acquireLease(60); // 60 second lease
System.out.println("Acquired lease: " + leaseId);
try {
// Operations with lease
BlobRequestConditions leaseConditions = new BlobRequestConditions()
.setLeaseId(leaseId);
containerClient.setMetadataWithResponse(
Map.of("leased", "true"),
leaseConditions,
Duration.ofSeconds(30),
Context.NONE
);
// Renew lease
leaseClient.renewLease();
// Break lease (if needed)
Integer breakPeriod = leaseClient.breakLease();
System.out.println("Lease will be broken in " + breakPeriod + " seconds");
} finally {
// Always release lease
try {
leaseClient.releaseLease();
System.out.println("Lease released");
} catch (Exception ex) {
System.err.println("Failed to release lease: " + ex.getMessage());
}
}// Container identification
String containerName = containerClient.getBlobContainerName();
String accountName = containerClient.getAccountName();
String containerUrl = containerClient.getBlobContainerUrl();
System.out.println("Container: " + containerName);
System.out.println("Account: " + accountName);
System.out.println("URL: " + containerUrl);
// Service information
BlobServiceVersion serviceVersion = containerClient.getServiceVersion();
System.out.println("Service version: " + serviceVersion.getVersion());
// Get account info through container
StorageAccountInfo accountInfo = containerClient.getAccountInfo();
System.out.println("Account kind: " + accountInfo.getAccountKind());
System.out.println("SKU: " + accountInfo.getSkuName());// Root container ($root) - blobs accessible at account level
BlobContainerClient rootContainer = serviceClient.getBlobContainerClient(BlobContainerClient.ROOT_CONTAINER_NAME);
// Static website container ($web)
BlobContainerClient webContainer = serviceClient.getBlobContainerClient(BlobContainerClient.STATIC_WEBSITE_CONTAINER_NAME);
// Logs container ($logs) - for analytics logging
BlobContainerClient logsContainer = serviceClient.getBlobContainerClient(BlobContainerClient.LOG_CONTAINER_NAME);
// Check if system containers exist before using
if (rootContainer.exists()) {
System.out.println("Root container is available");
}
// Upload to root container (blob accessible at https://account.blob.core.windows.net/filename)
BlobClient rootBlob = rootContainer.getBlobClient("favicon.ico");
rootBlob.uploadFromFile("favicon.ico");// Process multiple containers
List<String> containerNames = Arrays.asList("container1", "container2", "container3");
// Create multiple containers
containerNames.forEach(name -> {
try {
BlobContainerClient client = serviceClient.getBlobContainerClient(name);
client.createIfNotExists();
System.out.println("Ensured container exists: " + name);
} catch (Exception ex) {
System.err.println("Failed to create container " + name + ": " + ex.getMessage());
}
});
// Set metadata on multiple containers
Map<String, String> commonMetadata = Map.of(
"batch-operation", "true",
"timestamp", OffsetDateTime.now().toString()
);
containerNames.forEach(name -> {
try {
BlobContainerClient client = serviceClient.getBlobContainerClient(name);
if (client.exists()) {
client.setMetadata(commonMetadata);
System.out.println("Set metadata on: " + name);
}
} catch (Exception ex) {
System.err.println("Failed to set metadata on " + name + ": " + ex.getMessage());
}
});Install with Tessl CLI
npx tessl i tessl/maven-com-azure--azure-storage-blob