[英]How to create Container and upload Data with only SAS with AzureBlobStorage Java SDK v10
我从我的大学获得了一个 SAS 令牌。 SAS 令牌如下所示:
他说我可以用它来创建容器并将数据推送到这个容器中。 所以我开始在一些例子的帮助下编码。 我想出了这个:
public ContainerURL getContainerURL() throws MalformedURLException {
// From the Azure portal, get your Storage account's name and account key.
String storgeResourceUri = "https://<account>.blob.core.windows.net";
String sasToken = "https://myaccount.blob.core.windows.net/?sv=2015-04-05&st=2015-04-29T22%3A18%3A26Z&se=2015-04-30T02%3A23%3A26Z&sr=b&sp=rw&sip=168.1.5.60-168.1.5.70&spr=https&sig=Z%2FRHIX5Xcg0Mq2rqI3OlWTjEg2tYkboXr1P9ZUXDtkk%3D";
StorageCredentialsSharedAccessSignature creds = new StorageCredentialsSharedAccessSignature(sasToken);
// Create a ServiceURL objet that wraps the service URL and a request pipeline.
ServiceURL serviceURL = new ServiceURL(new URL(storgeResourceUri), StorageURL.createPipeline(creds, new PipelineOptions()));
// Now you can use the ServiceURL to perform various container and blob operations.
// This example shows several common operations just to get you started.
/*
Create a URL that references a to-be-created container in your Azure Storage account. This returns a
ContainerURL object that wraps the container's URL and a request pipeline (inherited from serviceURL).
Note that container names require lowercase.
*/
return serviceURL.createContainerURL("mapupdate-container");
}
public void uploadFile(ContainerURL containerURL, File sourceFile) throws IOException {
String timeStamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
File zippedFile = zipping(sourceFile, timeStamp);
BlockBlobURL blobURL = containerURL.createBlockBlobURL(zippedFile.getName());
AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(zippedFile.toPath());
// Uploading a file to the blobURL using the high-level methods available in TransferManager class
// Alternatively call the Upload/StageBlock low-level methods from BlockBlobURL type
TransferManager.uploadFileToBlockBlob(fileChannel, blobURL, (int) zippedFile.length(), null)
.subscribe(response -> {
System.out.println("Completed upload request.");
System.out.println(response.response().statusCode());
});
}
它应该创建一个名为“mapudpater-container”的容器,然后上传一个压缩文件。 之后我想通过 mqtt 发送它,另一个客户端可以使用链接下载它。
我不确定如何使用 SAS 令牌访问 Azure Blob 存储帐户并创建容器并将文件上传到容器中。 我应该为每个文件创建一个新容器吗? 我如何获得链接以从中下载? 我是否必须创建自己的 SAS 令牌才能下载它?
有两种使用 Java 与 AzureBlobStorage 交互和管理文件的方法,
Azure 存储 Blob - 它使用基于 REST 的机制与 Azure 存储 Blob 连接并管理文件。 它相对较慢。
<dependency> <groupId>com.microsoft.azure</groupId> <artifactId>azure-storage-blob</artifactId> <version>11.0.0</version> </dependency>
Azure 存储 - 它是 Azure 提供的云 API,比基于 REST 的 API 更快
<dependency> <groupId>com.microsoft.azure</groupId> <artifactId>azure-storage</artifactId> <version>8.6.4</version> </dependency>
下面为两种类型的实现创建了实用程序:
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.security.InvalidKeyException;
import java.util.Calendar;
import java.util.EnumSet;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.Objects;
import java.util.TimeZone;
import com.microsoft.azure.storage.CloudStorageAccount;
import com.microsoft.azure.storage.StorageException;
import com.microsoft.azure.storage.blob.BlockBlobURL;
import com.microsoft.azure.storage.blob.CloudBlobClient;
import com.microsoft.azure.storage.blob.CloudBlobContainer;
import com.microsoft.azure.storage.blob.CloudBlockBlob;
import com.microsoft.azure.storage.blob.ContainerURL;
import com.microsoft.azure.storage.blob.DownloadResponse;
import com.microsoft.azure.storage.blob.PipelineOptions;
import com.microsoft.azure.storage.blob.ServiceURL;
import com.microsoft.azure.storage.blob.SharedAccessBlobPermissions;
import com.microsoft.azure.storage.blob.SharedAccessBlobPolicy;
import com.microsoft.azure.storage.blob.SharedKeyCredentials;
import com.microsoft.azure.storage.blob.StorageURL;
import com.microsoft.azure.storage.blob.models.BlobDeleteResponse;
import com.microsoft.azure.storage.blob.models.BlockBlobUploadResponse;
import com.microsoft.azure.storage.core.Base64;
import com.microsoft.rest.v2.http.HttpPipeline;
import com.microsoft.rest.v2.util.FlowableUtil;
import io.reactivex.Flowable;
import io.reactivex.Single;
public class AzureStorageUtils {
public static void main(String...args) throws Exception {
FileInputStream fis = new FileInputStream("test.pdf");
int available = fis.available();
byte[] buffer = new byte[available];
fis.read(buffer);
fis.close();
String accountName = "enter azure account name";
String accountKey = "enter account key ";
BlobFile file = new BlobFile();
file.setFileType("image");
file.setFileName("directory1/image.pdf");
file.setFileSize(available);
file.setContent(buffer);
long startTime = System.currentTimeMillis();
uploadFile(accountName, accountKey, file);
//deleteFile(accountName, accountKey, file);
long endTime = System.currentTimeMillis();
System.out.println("Start Time: " + startTime);
System.out.println("End Time: " + endTime);
System.out.println("Time Taken: " + (endTime - startTime));
String connectionString = "entery connection string for azure blob";
startTime = System.currentTimeMillis();
create(connectionString, "image", "directory1/image.pdf", buffer);
endTime = System.currentTimeMillis();
System.out.println("Start Time: " + startTime);
System.out.println("End Time: " + endTime);
System.out.println("Time Taken: " + (endTime - startTime));
startTime = System.currentTimeMillis();
byte[] temp = read(connectionString, "image", "directory1/image.pdf");
System.out.println(Base64.encode(temp));
endTime = System.currentTimeMillis();
System.out.println("Start Time: " + startTime);
System.out.println("End Time: " + endTime);
System.out.println("Time Taken: " + (endTime - startTime));
startTime = System.currentTimeMillis();
String sasURL = sasURL(connectionString, "image", "directory1/image.pdf");
System.out.println(sasURL);
endTime = System.currentTimeMillis();
System.out.println("Start Time: " + startTime);
System.out.println("End Time: " + endTime);
System.out.println("Time Taken: " + (endTime - startTime));
startTime = System.currentTimeMillis();
delete(connectionString, "image", "directory1/image.pdf");
endTime = System.currentTimeMillis();
System.out.println("Start Time: " + startTime);
System.out.println("End Time: " + endTime);
System.out.println("Time Taken: " + (endTime - startTime));
}
/**
* azure-storage
*/
private static CloudBlobClient createCloudBlobClient(String connectionString) throws InvalidKeyException, URISyntaxException {
CloudStorageAccount account = CloudStorageAccount.parse(connectionString);
return account.createCloudBlobClient();
}
private static CloudBlobContainer getBlobConatiner(String connectionString, String containerName) throws InvalidKeyException, URISyntaxException, StorageException {
CloudBlobClient cloudBlobClient = createCloudBlobClient(connectionString);
CloudBlobContainer cloudBlobContainer = cloudBlobClient.getContainerReference(containerName);
cloudBlobContainer.createIfNotExists();
return cloudBlobContainer;
}
public static CloudBlockBlob create(String connectionString, String containerName, String filePath, byte[] data) throws RuntimeException {
try {
CloudBlobContainer cloudBlobContainer = getBlobConatiner(connectionString, containerName);
CloudBlockBlob cloudBlockBlob = cloudBlobContainer.getBlockBlobReference(filePath);
cloudBlockBlob.uploadFromByteArray(data, 0, data.length);
return cloudBlockBlob;
}
catch(InvalidKeyException | URISyntaxException | StorageException | IOException ex) {
throw new RuntimeException();
}
}
public static byte[] read(String connectionString, String containerName, String filePath) throws RuntimeException {
try {
CloudBlobContainer cloudBlobContainer = getBlobConatiner(connectionString, containerName);
CloudBlockBlob cloudBlockBlob = cloudBlobContainer.getBlockBlobReference(filePath);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
cloudBlockBlob.download(outputStream);
byte[] byteArray = outputStream.toByteArray();
outputStream.close();
return byteArray;
}
catch(InvalidKeyException | URISyntaxException | StorageException | IOException ex) {
throw new RuntimeException();
}
}
public static boolean delete(String connectionString, String containerName, String filePath) throws RuntimeException {
try {
CloudBlobContainer cloudBlobContainer = getBlobConatiner(connectionString, containerName);
CloudBlockBlob cloudBlockBlob = cloudBlobContainer.getBlockBlobReference(filePath);
return cloudBlockBlob.deleteIfExists();
}
catch(InvalidKeyException | URISyntaxException | StorageException ex) {
throw new RuntimeException();
}
}
public static String sasURL(String connectionString, String containerName, String filePath) throws RuntimeException {
try {
CloudBlobContainer cloudBlobContainer = getBlobConatiner(connectionString, containerName);
CloudBlockBlob cloudBlockBlob = cloudBlobContainer.getBlockBlobReference(filePath);
SharedAccessBlobPolicy sasPolicy = new SharedAccessBlobPolicy();
GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
calendar.add(Calendar.HOUR, 10);
sasPolicy.setSharedAccessExpiryTime(calendar.getTime());
sasPolicy.setPermissions(EnumSet.of(SharedAccessBlobPermissions.READ, SharedAccessBlobPermissions.WRITE, SharedAccessBlobPermissions.LIST));
String sas = cloudBlockBlob.generateSharedAccessSignature(sasPolicy,null);
return cloudBlockBlob.getUri()+"?"+sas;
}
catch(InvalidKeyException | URISyntaxException | StorageException ex) {
throw new RuntimeException();
}
}
/**
* azure-storage-blob
*/
private static BlockBlobURL getBlobURL(String accountName, String accountKey, String containerName, String filename) throws Exception {
ContainerURL containerURL = null;
BlockBlobURL blobURL = null;
try {
SharedKeyCredentials credential = new SharedKeyCredentials(accountName, accountKey);
HttpPipeline pipeline = StorageURL.createPipeline(credential, new PipelineOptions());
URL url = new URL(String.format(Locale.ROOT, "https://%s.blob.core.windows.net", accountName));
ServiceURL serviceURL = new ServiceURL(url, pipeline);
containerURL = serviceURL.createContainerURL(containerName);
blobURL = containerURL.createBlockBlobURL(filename);
} catch (Exception e) {
throw new Exception(e.getMessage());
}
return blobURL;
}
public static boolean uploadFile(String accountName, String accountKey, BlobFile file) throws Exception {
boolean isUploaded = false;
if (Objects.isNull(file.getFileType())) {
throw new Exception("FileType is missing");
}
if (Objects.isNull(file.getFileName())) {
throw new Exception("FileName is missing");
}
if (Objects.isNull(file.getContent())) {
throw new Exception("Content is missing");
}
if (file.getFileSize() == 0) {
throw new Exception("File's size is missing");
}
BlockBlobURL blobURL = getBlobURL(accountName, accountKey, file.getFileType(), file.getFileName());
Single<BlockBlobUploadResponse> blobResponse = blobURL.upload(Flowable.just(ByteBuffer.wrap(file.getContent())), file.getFileSize(), null, null, null, null);
if (blobResponse.blockingGet().statusCode() == 201) {
isUploaded = true;
}
return isUploaded;
}
public static BlobFile downloadFile(String accountName, String accountKey, BlobFile file) throws Exception {
if (Objects.isNull(file.getFileType())) {
throw new Exception("FileType is missing");
}
if (Objects.isNull(file.getFileName())) {
throw new Exception("FileName is missing");
}
BlockBlobURL blobURL = getBlobURL(accountName, accountKey, file.getFileType(), file.getFileName());
Single<DownloadResponse> blobResponse = blobURL.download(null, null, false, null);
Flowable<ByteBuffer> fByteBuffer = blobResponse.blockingGet().body(null);
Single<ByteBuffer> bf = FlowableUtil.collectBytesInBuffer(fByteBuffer);
file.setContent(bf.blockingGet().array());
return file;
}
public static boolean deleteFile(String accountName, String accountKey, BlobFile file) throws Exception {
boolean flag = false;
if (Objects.isNull(file.getFileType())) {
throw new Exception("FileType is missing");
}
if (Objects.isNull(file.getFileName())) {
throw new Exception("FileName is missing");
}
BlockBlobURL blobURL = getBlobURL(accountName, accountKey, file.getFileType(), file.getFileName());
Single<BlobDeleteResponse> blobResponse = blobURL.delete(null, null, null);
if (blobResponse.blockingGet().statusCode() == 201) {
flag = true;
}
return flag;
}
}
上述解决方案有两种实现方式,我们还比较了相同活动(如上传相同文件)所花费的时间。
首选方法是使用 azure-storage 依赖项。
您可以使用 SAS 作为连接字符串的凭据。 连接字符串格式是(包括换行符只是为了便于阅读):
BlobEndpoint=myBlobEndpoint; QueueEndpoint=myQueueEndpoint; TableEndpoint=myTableEndpoint; FileEndpoint=myFileEndpoint; SharedAccessSignature=sasToken
有关更多信息,您还可以参考SO线程中提到的建议。
在本操作指南中,您将了解如何使用 Java 客户端库上传、下载和列出 Azure Blob 存储容器中的块 Blob 。
以下是展示如何使用com.microsoft.azure.storage.blob.CloudBlockBlob 类的upload() 的Java 代码示例。
附加信息:本主题展示了共享访问签名与 REST API 的示例使用。 共享访问签名允许您提供对容器和 Blob、表、队列或文件的访问权限。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.