[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71816F5GD4RKAEN2EZ8VZRE":3,"skill-same:01M71816F5GD4RKAEN2EZ8VZRE":59},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":33,"linkOnly":34,"markdownContent":35,"markdownBody":36,"frontMatter":37,"refName":39,"commitSha":40,"skillDirectory":41,"forksCount":14,"repositoryHtmlUrl":42,"repositoryHomepageUrl":6,"ownerHtmlUrl":43,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":44,"install":45,"resources":58},"01M71816F5GD4RKAEN2EZ8VZRE","azure-storage-blob-java",null,"Build blob storage applications using the Azure Storage Blob SDK for Java.","sapsapshen\u002Fai-memory-router","sapsapshen","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F20347959?v=4","01M6XDQEF1DP50DKF37H81J3J5","shenmian","01M6XDQEJPE41Y3DT2763X8ZJN",0,"MIT","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fglobal\u002Fazure-storage-blob-java\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32],"storage","azure storage","azure","azure storage blob java","java","blob","sdk","applications","build","community","for","unknown","blob storage","2026","2026-11-10 10:12:30",false,"---\nname: azure-storage-blob-java\ndescription: \"Build blob storage applications using the Azure Storage Blob SDK for Java.\"\nrisk: unknown\nsource: community\ndate_added: \"2026-02-27\"\n---\n\n# Azure Storage Blob SDK for Java\n\nBuild blob storage applications using the Azure Storage Blob SDK for Java.\n\n## Installation\n\n```xml\n\u003Cdependency>\n    \u003CgroupId>com.azure\u003C\u002FgroupId>\n    \u003CartifactId>azure-storage-blob\u003C\u002FartifactId>\n    \u003Cversion>12.33.0\u003C\u002Fversion>\n\u003C\u002Fdependency>\n```\n\n## Client Creation\n\n### BlobServiceClient\n\n```java\nimport com.azure.storage.blob.BlobServiceClient;\nimport com.azure.storage.blob.BlobServiceClientBuilder;\n\n\u002F\u002F With SAS token\nBlobServiceClient serviceClient = new BlobServiceClientBuilder()\n    .endpoint(\"\u003Cstorage-account-url>\")\n    .sasToken(\"\u003Csas-token>\")\n    .buildClient();\n\n\u002F\u002F With connection string\nBlobServiceClient serviceClient = new BlobServiceClientBuilder()\n    .connectionString(\"\u003Cconnection-string>\")\n    .buildClient();\n```\n\n### With DefaultAzureCredential\n\n```java\nimport com.azure.identity.DefaultAzureCredentialBuilder;\n\nBlobServiceClient serviceClient = new BlobServiceClientBuilder()\n    .endpoint(\"\u003Cstorage-account-url>\")\n    .credential(new DefaultAzureCredentialBuilder().build())\n    .buildClient();\n```\n\n### BlobContainerClient\n\n```java\nimport com.azure.storage.blob.BlobContainerClient;\n\n\u002F\u002F From service client\nBlobContainerClient containerClient = serviceClient.getBlobContainerClient(\"mycontainer\");\n\n\u002F\u002F Direct construction\nBlobContainerClient containerClient = new BlobContainerClientBuilder()\n    .connectionString(\"\u003Cconnection-string>\")\n    .containerName(\"mycontainer\")\n    .buildClient();\n```\n\n### BlobClient\n\n```java\nimport com.azure.storage.blob.BlobClient;\n\n\u002F\u002F From container client\nBlobClient blobClient = containerClient.getBlobClient(\"myblob.txt\");\n\n\u002F\u002F With directory structure\nBlobClient blobClient = containerClient.getBlobClient(\"folder\u002Fsubfolder\u002Fmyblob.txt\");\n\n\u002F\u002F Direct construction\nBlobClient blobClient = new BlobClientBuilder()\n    .connectionString(\"\u003Cconnection-string>\")\n    .containerName(\"mycontainer\")\n    .blobName(\"myblob.txt\")\n    .buildClient();\n```\n\n## Core Patterns\n\n### Create Container\n\n```java\n\u002F\u002F Create container\nserviceClient.createBlobContainer(\"mycontainer\");\n\n\u002F\u002F Create if not exists\nBlobContainerClient container = serviceClient.createBlobContainerIfNotExists(\"mycontainer\");\n\n\u002F\u002F From container client\ncontainerClient.create();\ncontainerClient.createIfNotExists();\n```\n\n### Upload Data\n\n```java\nimport com.azure.core.util.BinaryData;\n\n\u002F\u002F Upload string\nString data = \"Hello, Azure Blob Storage!\";\nblobClient.upload(BinaryData.fromString(data));\n\n\u002F\u002F Upload with overwrite\nblobClient.upload(BinaryData.fromString(data), true);\n```\n\n### Upload from File\n\n```java\nblobClient.uploadFromFile(\"local-file.txt\");\n\n\u002F\u002F With overwrite\nblobClient.uploadFromFile(\"local-file.txt\", true);\n```\n\n### Upload from Stream\n\n```java\nimport com.azure.storage.blob.specialized.BlockBlobClient;\n\nBlockBlobClient blockBlobClient = blobClient.getBlockBlobClient();\n\ntry (ByteArrayInputStream dataStream = new ByteArrayInputStream(data.getBytes())) {\n    blockBlobClient.upload(dataStream, data.length());\n}\n```\n\n### Upload with Options\n\n```java\nimport com.azure.storage.blob.models.BlobHttpHeaders;\nimport com.azure.storage.blob.options.BlobParallelUploadOptions;\n\nBlobHttpHeaders headers = new BlobHttpHeaders()\n    .setContentType(\"text\u002Fplain\")\n    .setCacheControl(\"max-age=3600\");\n\nMap\u003CString, String> metadata = Map.of(\"author\", \"john\", \"version\", \"1.0\");\n\ntry (InputStream stream = new FileInputStream(\"large-file.bin\")) {\n    BlobParallelUploadOptions options = new BlobParallelUploadOptions(stream)\n        .setHeaders(headers)\n        .setMetadata(metadata);\n    \n    blobClient.uploadWithResponse(options, null, Context.NONE);\n}\n```\n\n### Upload if Not Exists\n\n```java\nimport com.azure.storage.blob.models.BlobRequestConditions;\n\nBlobParallelUploadOptions options = new BlobParallelUploadOptions(inputStream, length)\n    .setRequestConditions(new BlobRequestConditions().setIfNoneMatch(\"*\"));\n\nblobClient.uploadWithResponse(options, null, Context.NONE);\n```\n\n### Download Data\n\n```java\n\u002F\u002F Download to BinaryData\nBinaryData content = blobClient.downloadContent();\nString text = content.toString();\n\n\u002F\u002F Download to file\nblobClient.downloadToFile(\"downloaded-file.txt\");\n```\n\n### Download to Stream\n\n```java\ntry (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {\n    blobClient.downloadStream(outputStream);\n    byte[] data = outputStream.toByteArray();\n}\n```\n\n### Download with InputStream\n\n```java\nimport com.azure.storage.blob.specialized.BlobInputStream;\n\ntry (BlobInputStream blobIS = blobClient.openInputStream()) {\n    byte[] buffer = new byte[1024];\n    int bytesRead;\n    while ((bytesRead = blobIS.read(buffer)) != -1) {\n        \u002F\u002F Process buffer\n    }\n}\n```\n\n### Upload via OutputStream\n\n```java\nimport com.azure.storage.blob.specialized.BlobOutputStream;\n\ntry (BlobOutputStream blobOS = blobClient.getBlockBlobClient().getBlobOutputStream()) {\n    blobOS.write(\"Data to upload\".getBytes());\n}\n```\n\n### List Blobs\n\n```java\nimport com.azure.storage.blob.models.BlobItem;\n\n\u002F\u002F List all blobs\nfor (BlobItem blobItem : containerClient.listBlobs()) {\n    System.out.println(\"Blob: \" + blobItem.getName());\n}\n\n\u002F\u002F List with prefix (virtual directory)\nimport com.azure.storage.blob.models.ListBlobsOptions;\n\nListBlobsOptions options = new ListBlobsOptions().setPrefix(\"folder\u002F\");\nfor (BlobItem blobItem : containerClient.listBlobs(options, null)) {\n    System.out.println(\"Blob: \" + blobItem.getName());\n}\n```\n\n### List Blobs by Hierarchy\n\n```java\nimport com.azure.storage.blob.models.BlobListDetails;\n\nString delimiter = \"\u002F\";\nListBlobsOptions options = new ListBlobsOptions()\n    .setPrefix(\"data\u002F\")\n    .setDetails(new BlobListDetails().setRetrieveMetadata(true));\n\nfor (BlobItem item : containerClient.listBlobsByHierarchy(delimiter, options, null)) {\n    if (item.isPrefix()) {\n        System.out.println(\"Directory: \" + item.getName());\n    } else {\n        System.out.println(\"Blob: \" + item.getName());\n    }\n}\n```\n\n### Delete Blob\n\n```java\nblobClient.delete();\n\n\u002F\u002F Delete if exists\nblobClient.deleteIfExists();\n\n\u002F\u002F Delete with snapshots\nimport com.azure.storage.blob.models.DeleteSnapshotsOptionType;\nblobClient.deleteWithResponse(DeleteSnapshotsOptionType.INCLUDE, null, null, Context.NONE);\n```\n\n### Copy Blob\n\n```java\nimport com.azure.storage.blob.models.BlobCopyInfo;\nimport com.azure.core.util.polling.SyncPoller;\n\n\u002F\u002F Async copy (for large blobs or cross-account)\nSyncPoller\u003CBlobCopyInfo, Void> poller = blobClient.beginCopy(\"\u003Csource-blob-url>\", Duration.ofSeconds(1));\npoller.waitForCompletion();\n\n\u002F\u002F Sync copy from URL (for same account)\nblobClient.copyFromUrl(\"\u003Csource-blob-url>\");\n```\n\n### Generate SAS Token\n\n```java\nimport com.azure.storage.blob.sas.*;\nimport java.time.OffsetDateTime;\n\n\u002F\u002F Blob-level SAS\nBlobSasPermission permissions = new BlobSasPermission().setReadPermission(true);\nOffsetDateTime expiry = OffsetDateTime.now().plusDays(1);\n\nBlobServiceSasSignatureValues sasValues = new BlobServiceSasSignatureValues(expiry, permissions);\nString sasToken = blobClient.generateSas(sasValues);\n\n\u002F\u002F Container-level SAS\nBlobContainerSasPermission containerPermissions = new BlobContainerSasPermission()\n    .setReadPermission(true)\n    .setListPermission(true);\n    \nBlobServiceSasSignatureValues containerSasValues = new BlobServiceSasSignatureValues(expiry, containerPermissions);\nString containerSas = containerClient.generateSas(containerSasValues);\n```\n\n### Blob Properties and Metadata\n\n```java\nimport com.azure.storage.blob.models.BlobProperties;\n\n\u002F\u002F Get properties\nBlobProperties properties = blobClient.getProperties();\nSystem.out.println(\"Size: \" + properties.getBlobSize());\nSystem.out.println(\"Content-Type: \" + properties.getContentType());\nSystem.out.println(\"Last Modified: \" + properties.getLastModified());\n\n\u002F\u002F Set metadata\nMap\u003CString, String> metadata = Map.of(\"key1\", \"value1\", \"key2\", \"value2\");\nblobClient.setMetadata(metadata);\n\n\u002F\u002F Set HTTP headers\nBlobHttpHeaders headers = new BlobHttpHeaders()\n    .setContentType(\"application\u002Fjson\")\n    .setCacheControl(\"max-age=86400\");\nblobClient.setHttpHeaders(headers);\n```\n\n### Lease Blob\n\n```java\nimport com.azure.storage.blob.specialized.BlobLeaseClient;\nimport com.azure.storage.blob.specialized.BlobLeaseClientBuilder;\n\nBlobLeaseClient leaseClient = new BlobLeaseClientBuilder()\n    .blobClient(blobClient)\n    .buildClient();\n\n\u002F\u002F Acquire lease (-1 for infinite)\nString leaseId = leaseClient.acquireLease(60);\n\n\u002F\u002F Renew lease\nleaseClient.renewLease();\n\n\u002F\u002F Release lease\nleaseClient.releaseLease();\n```\n\n## Error Handling\n\n```java\nimport com.azure.storage.blob.models.BlobStorageException;\n\ntry {\n    blobClient.download(outputStream);\n} catch (BlobStorageException e) {\n    System.out.println(\"Status: \" + e.getStatusCode());\n    System.out.println(\"Error code: \" + e.getErrorCode());\n    \u002F\u002F 404 = Blob not found\n    \u002F\u002F 409 = Conflict (lease, etc.)\n}\n```\n\n## Proxy Configuration\n\n```java\nimport com.azure.core.http.ProxyOptions;\nimport com.azure.core.http.netty.NettyAsyncHttpClientBuilder;\nimport java.net.InetSocketAddress;\n\nProxyOptions proxyOptions = new ProxyOptions(\n    ProxyOptions.Type.HTTP,\n    new InetSocketAddress(\"localhost\", 8888));\n\nBlobServiceClient client = new BlobServiceClientBuilder()\n    .endpoint(\"\u003Cendpoint>\")\n    .sasToken(\"\u003Csas-token>\")\n    .httpClient(new NettyAsyncHttpClientBuilder().proxy(proxyOptions).build())\n    .buildClient();\n```\n\n## Environment Variables\n\n```bash\nAZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...\nAZURE_STORAGE_ACCOUNT_URL=https:\u002F\u002F\u003Caccount>.blob.core.windows.net\n```\n\n## Trigger Phrases\n\n- \"Azure Blob Storage Java\"\n- \"upload download blob\"\n- \"blob container SDK\"\n- \"storage streaming\"\n- \"SAS token generation\"\n- \"blob metadata properties\"\n\n## When to Use\nThis skill is applicable to execute the workflow or actions described in the overview.\n","# Azure Storage Blob SDK for Java\n\nBuild blob storage applications using the Azure Storage Blob SDK for Java.\n\n## Installation\n\n```xml\n\u003Cdependency>\n    \u003CgroupId>com.azure\u003C\u002FgroupId>\n    \u003CartifactId>azure-storage-blob\u003C\u002FartifactId>\n    \u003Cversion>12.33.0\u003C\u002Fversion>\n\u003C\u002Fdependency>\n```\n\n## Client Creation\n\n### BlobServiceClient\n\n```java\nimport com.azure.storage.blob.BlobServiceClient;\nimport com.azure.storage.blob.BlobServiceClientBuilder;\n\n\u002F\u002F With SAS token\nBlobServiceClient serviceClient = new BlobServiceClientBuilder()\n    .endpoint(\"\u003Cstorage-account-url>\")\n    .sasToken(\"\u003Csas-token>\")\n    .buildClient();\n\n\u002F\u002F With connection string\nBlobServiceClient serviceClient = new BlobServiceClientBuilder()\n    .connectionString(\"\u003Cconnection-string>\")\n    .buildClient();\n```\n\n### With DefaultAzureCredential\n\n```java\nimport com.azure.identity.DefaultAzureCredentialBuilder;\n\nBlobServiceClient serviceClient = new BlobServiceClientBuilder()\n    .endpoint(\"\u003Cstorage-account-url>\")\n    .credential(new DefaultAzureCredentialBuilder().build())\n    .buildClient();\n```\n\n### BlobContainerClient\n\n```java\nimport com.azure.storage.blob.BlobContainerClient;\n\n\u002F\u002F From service client\nBlobContainerClient containerClient = serviceClient.getBlobContainerClient(\"mycontainer\");\n\n\u002F\u002F Direct construction\nBlobContainerClient containerClient = new BlobContainerClientBuilder()\n    .connectionString(\"\u003Cconnection-string>\")\n    .containerName(\"mycontainer\")\n    .buildClient();\n```\n\n### BlobClient\n\n```java\nimport com.azure.storage.blob.BlobClient;\n\n\u002F\u002F From container client\nBlobClient blobClient = containerClient.getBlobClient(\"myblob.txt\");\n\n\u002F\u002F With directory structure\nBlobClient blobClient = containerClient.getBlobClient(\"folder\u002Fsubfolder\u002Fmyblob.txt\");\n\n\u002F\u002F Direct construction\nBlobClient blobClient = new BlobClientBuilder()\n    .connectionString(\"\u003Cconnection-string>\")\n    .containerName(\"mycontainer\")\n    .blobName(\"myblob.txt\")\n    .buildClient();\n```\n\n## Core Patterns\n\n### Create Container\n\n```java\n\u002F\u002F Create container\nserviceClient.createBlobContainer(\"mycontainer\");\n\n\u002F\u002F Create if not exists\nBlobContainerClient container = serviceClient.createBlobContainerIfNotExists(\"mycontainer\");\n\n\u002F\u002F From container client\ncontainerClient.create();\ncontainerClient.createIfNotExists();\n```\n\n### Upload Data\n\n```java\nimport com.azure.core.util.BinaryData;\n\n\u002F\u002F Upload string\nString data = \"Hello, Azure Blob Storage!\";\nblobClient.upload(BinaryData.fromString(data));\n\n\u002F\u002F Upload with overwrite\nblobClient.upload(BinaryData.fromString(data), true);\n```\n\n### Upload from File\n\n```java\nblobClient.uploadFromFile(\"local-file.txt\");\n\n\u002F\u002F With overwrite\nblobClient.uploadFromFile(\"local-file.txt\", true);\n```\n\n### Upload from Stream\n\n```java\nimport com.azure.storage.blob.specialized.BlockBlobClient;\n\nBlockBlobClient blockBlobClient = blobClient.getBlockBlobClient();\n\ntry (ByteArrayInputStream dataStream = new ByteArrayInputStream(data.getBytes())) {\n    blockBlobClient.upload(dataStream, data.length());\n}\n```\n\n### Upload with Options\n\n```java\nimport com.azure.storage.blob.models.BlobHttpHeaders;\nimport com.azure.storage.blob.options.BlobParallelUploadOptions;\n\nBlobHttpHeaders headers = new BlobHttpHeaders()\n    .setContentType(\"text\u002Fplain\")\n    .setCacheControl(\"max-age=3600\");\n\nMap\u003CString, String> metadata = Map.of(\"author\", \"john\", \"version\", \"1.0\");\n\ntry (InputStream stream = new FileInputStream(\"large-file.bin\")) {\n    BlobParallelUploadOptions options = new BlobParallelUploadOptions(stream)\n        .setHeaders(headers)\n        .setMetadata(metadata);\n    \n    blobClient.uploadWithResponse(options, null, Context.NONE);\n}\n```\n\n### Upload if Not Exists\n\n```java\nimport com.azure.storage.blob.models.BlobRequestConditions;\n\nBlobParallelUploadOptions options = new BlobParallelUploadOptions(inputStream, length)\n    .setRequestConditions(new BlobRequestConditions().setIfNoneMatch(\"*\"));\n\nblobClient.uploadWithResponse(options, null, Context.NONE);\n```\n\n### Download Data\n\n```java\n\u002F\u002F Download to BinaryData\nBinaryData content = blobClient.downloadContent();\nString text = content.toString();\n\n\u002F\u002F Download to file\nblobClient.downloadToFile(\"downloaded-file.txt\");\n```\n\n### Download to Stream\n\n```java\ntry (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {\n    blobClient.downloadStream(outputStream);\n    byte[] data = outputStream.toByteArray();\n}\n```\n\n### Download with InputStream\n\n```java\nimport com.azure.storage.blob.specialized.BlobInputStream;\n\ntry (BlobInputStream blobIS = blobClient.openInputStream()) {\n    byte[] buffer = new byte[1024];\n    int bytesRead;\n    while ((bytesRead = blobIS.read(buffer)) != -1) {\n        \u002F\u002F Process buffer\n    }\n}\n```\n\n### Upload via OutputStream\n\n```java\nimport com.azure.storage.blob.specialized.BlobOutputStream;\n\ntry (BlobOutputStream blobOS = blobClient.getBlockBlobClient().getBlobOutputStream()) {\n    blobOS.write(\"Data to upload\".getBytes());\n}\n```\n\n### List Blobs\n\n```java\nimport com.azure.storage.blob.models.BlobItem;\n\n\u002F\u002F List all blobs\nfor (BlobItem blobItem : containerClient.listBlobs()) {\n    System.out.println(\"Blob: \" + blobItem.getName());\n}\n\n\u002F\u002F List with prefix (virtual directory)\nimport com.azure.storage.blob.models.ListBlobsOptions;\n\nListBlobsOptions options = new ListBlobsOptions().setPrefix(\"folder\u002F\");\nfor (BlobItem blobItem : containerClient.listBlobs(options, null)) {\n    System.out.println(\"Blob: \" + blobItem.getName());\n}\n```\n\n### List Blobs by Hierarchy\n\n```java\nimport com.azure.storage.blob.models.BlobListDetails;\n\nString delimiter = \"\u002F\";\nListBlobsOptions options = new ListBlobsOptions()\n    .setPrefix(\"data\u002F\")\n    .setDetails(new BlobListDetails().setRetrieveMetadata(true));\n\nfor (BlobItem item : containerClient.listBlobsByHierarchy(delimiter, options, null)) {\n    if (item.isPrefix()) {\n        System.out.println(\"Directory: \" + item.getName());\n    } else {\n        System.out.println(\"Blob: \" + item.getName());\n    }\n}\n```\n\n### Delete Blob\n\n```java\nblobClient.delete();\n\n\u002F\u002F Delete if exists\nblobClient.deleteIfExists();\n\n\u002F\u002F Delete with snapshots\nimport com.azure.storage.blob.models.DeleteSnapshotsOptionType;\nblobClient.deleteWithResponse(DeleteSnapshotsOptionType.INCLUDE, null, null, Context.NONE);\n```\n\n### Copy Blob\n\n```java\nimport com.azure.storage.blob.models.BlobCopyInfo;\nimport com.azure.core.util.polling.SyncPoller;\n\n\u002F\u002F Async copy (for large blobs or cross-account)\nSyncPoller\u003CBlobCopyInfo, Void> poller = blobClient.beginCopy(\"\u003Csource-blob-url>\", Duration.ofSeconds(1));\npoller.waitForCompletion();\n\n\u002F\u002F Sync copy from URL (for same account)\nblobClient.copyFromUrl(\"\u003Csource-blob-url>\");\n```\n\n### Generate SAS Token\n\n```java\nimport com.azure.storage.blob.sas.*;\nimport java.time.OffsetDateTime;\n\n\u002F\u002F Blob-level SAS\nBlobSasPermission permissions = new BlobSasPermission().setReadPermission(true);\nOffsetDateTime expiry = OffsetDateTime.now().plusDays(1);\n\nBlobServiceSasSignatureValues sasValues = new BlobServiceSasSignatureValues(expiry, permissions);\nString sasToken = blobClient.generateSas(sasValues);\n\n\u002F\u002F Container-level SAS\nBlobContainerSasPermission containerPermissions = new BlobContainerSasPermission()\n    .setReadPermission(true)\n    .setListPermission(true);\n    \nBlobServiceSasSignatureValues containerSasValues = new BlobServiceSasSignatureValues(expiry, containerPermissions);\nString containerSas = containerClient.generateSas(containerSasValues);\n```\n\n### Blob Properties and Metadata\n\n```java\nimport com.azure.storage.blob.models.BlobProperties;\n\n\u002F\u002F Get properties\nBlobProperties properties = blobClient.getProperties();\nSystem.out.println(\"Size: \" + properties.getBlobSize());\nSystem.out.println(\"Content-Type: \" + properties.getContentType());\nSystem.out.println(\"Last Modified: \" + properties.getLastModified());\n\n\u002F\u002F Set metadata\nMap\u003CString, String> metadata = Map.of(\"key1\", \"value1\", \"key2\", \"value2\");\nblobClient.setMetadata(metadata);\n\n\u002F\u002F Set HTTP headers\nBlobHttpHeaders headers = new BlobHttpHeaders()\n    .setContentType(\"application\u002Fjson\")\n    .setCacheControl(\"max-age=86400\");\nblobClient.setHttpHeaders(headers);\n```\n\n### Lease Blob\n\n```java\nimport com.azure.storage.blob.specialized.BlobLeaseClient;\nimport com.azure.storage.blob.specialized.BlobLeaseClientBuilder;\n\nBlobLeaseClient leaseClient = new BlobLeaseClientBuilder()\n    .blobClient(blobClient)\n    .buildClient();\n\n\u002F\u002F Acquire lease (-1 for infinite)\nString leaseId = leaseClient.acquireLease(60);\n\n\u002F\u002F Renew lease\nleaseClient.renewLease();\n\n\u002F\u002F Release lease\nleaseClient.releaseLease();\n```\n\n## Error Handling\n\n```java\nimport com.azure.storage.blob.models.BlobStorageException;\n\ntry {\n    blobClient.download(outputStream);\n} catch (BlobStorageException e) {\n    System.out.println(\"Status: \" + e.getStatusCode());\n    System.out.println(\"Error code: \" + e.getErrorCode());\n    \u002F\u002F 404 = Blob not found\n    \u002F\u002F 409 = Conflict (lease, etc.)\n}\n```\n\n## Proxy Configuration\n\n```java\nimport com.azure.core.http.ProxyOptions;\nimport com.azure.core.http.netty.NettyAsyncHttpClientBuilder;\nimport java.net.InetSocketAddress;\n\nProxyOptions proxyOptions = new ProxyOptions(\n    ProxyOptions.Type.HTTP,\n    new InetSocketAddress(\"localhost\", 8888));\n\nBlobServiceClient client = new BlobServiceClientBuilder()\n    .endpoint(\"\u003Cendpoint>\")\n    .sasToken(\"\u003Csas-token>\")\n    .httpClient(new NettyAsyncHttpClientBuilder().proxy(proxyOptions).build())\n    .buildClient();\n```\n\n## Environment Variables\n\n```bash\nAZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...\nAZURE_STORAGE_ACCOUNT_URL=https:\u002F\u002F\u003Caccount>.blob.core.windows.net\n```\n\n## Trigger Phrases\n\n- \"Azure Blob Storage Java\"\n- \"upload download blob\"\n- \"blob container SDK\"\n- \"storage streaming\"\n- \"SAS token generation\"\n- \"blob metadata properties\"\n\n## When to Use\nThis skill is applicable to execute the workflow or actions described in the overview.\n",{"name":5,"risk":30,"source":28,"date_added":38,"description":7},"2026-02-27","main","7a38d8e7073e61c16eda85681cb32fb68a8657a5","skills-store\u002Fglobal\u002Fazure-storage-blob-java","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router","https:\u002F\u002Fgithub.com\u002Fsapsapshen","2026-04-14 21:12:12",{"source":8,"skillName":5,"commands":46,"prompt":56,"zipAvailable":57},[47,50,53],{"tool":48,"command":49},"npx","npx skills add sapsapshen\u002Fai-memory-router --skill azure-storage-blob-java",{"tool":51,"command":52},"bunx","bunx skills add sapsapshen\u002Fai-memory-router --skill azure-storage-blob-java",{"tool":54,"command":55},"pnpm","pnpm dlx skills add sapsapshen\u002Fai-memory-router --skill azure-storage-blob-java","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fglobal\u002Fazure-storage-blob-java\u002FSKILL.md",true,[],[60,84,110,120,133,152],{"skillNo":61,"name":62,"nameZh":6,"description":63,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":64,"categories":65,"keywords":71,"publishedAt":33},"01M71ATQRKG48SH06FQ697T5G9","wechat-search","Search WeChat Official Account articles using OpenClaw's web search and fetch capabilities with compliance-focused design.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fwechat-search-release\u002FSKILL.md",[66],{"categoryNo":67,"categoryName":68,"taxonomyType":69,"taxonomyTypeDesc":70},"01JBSEEDCAT000000000000037","律师与法务","PROFESSION","适用职业",[72,73,74,75,76,77,78,79,80,81,82,83],"wechat search","wechat","search","capabilities","openclaw","design","web search","compliance","web","official","fetch","with",{"skillNo":85,"name":86,"nameZh":6,"description":87,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":90,"publishedAt":33},"01M71ATNAVGZB35PFYM2GC5N00","trend-tap","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend tap', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-tap\u002FSKILL.md",[],[91,92,93,94,95,96,74,97,98,99,100,101,102,103,104,105,106,107,108,109],"trend","trend tap","tap","api keys","Bash","time","trending","hacker","aggregator","do","when","brew","live","data","google","install","read","across","api",{"skillNo":111,"name":112,"nameZh":6,"description":113,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":116,"publishedAt":33},"01M71ATJ9AM5KM15AA8PS302EB","trend-radar","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend pulse', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-radar\u002FSKILL.md",[],[117,118,91,102,103,104,105,95,74,107,119,108,109,101,99,98,97,106,96,94],"trend radar","radar","pulse",{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":126,"publishedAt":33},"01M71ATGF095N3EJM9G8SD0BB5","tech-news-daily","每日科技新闻汇——从全球多个 RSS 源抓取最新科技新闻，翻译（英→中）、去重、排版成每日简报。当用户询问科技新闻、科技新鲜事、每日科技、技术动态、Daily Tech News 或类似表达时触发此技能。","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftech-news-daily\u002FSKILL.md",[],[127,128,129,130,131,132],"news","tech","tech news daily","daily","rss","翻译",{"skillNo":134,"name":135,"nameZh":6,"description":136,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":137,"categories":138,"keywords":144,"publishedAt":33},"01M71ATFAEAMQ17M70NQNY7SR8","summarize","Summarize URLs or files with the summarize CLI (web, PDFs, images, audio, YouTube).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsummarize\u002FSKILL.md",[139],{"categoryNo":140,"categoryName":141,"taxonomyType":142,"taxonomyTypeDesc":143},"01JBSEEDCAT000000000000021","资料检索与研究","SCENARIO","使用场景",[135,80,145,146,147,83,102,148,149,150,93,151,106],"Audio","cli","youtube","images","https","files","pdfs",{"skillNo":153,"name":154,"nameZh":6,"description":155,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":156,"categories":157,"keywords":158,"publishedAt":33},"01M71ATDNS3R0M4H936PACQAWZ","sonoscli","Control Sonos speakers (discover\u002Fstatus\u002Fplay\u002Fvolume\u002Fgroup).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsonoscli\u002FSKILL.md",[],[154,159,160,161,106,162,149,163,164,165,166,167],"status","play","go","latest","github","discover","control","cmd","volume"]