如何在Java中将Azure Blob存储内容获取到FileInputStream中?

huangapple go评论104阅读模式
英文:

How to get azure blob storage content in FileInputStream in Java?

问题

我正在开发一个API(使用Spring Boot)。在这个API中,我需要在GET方法的响应体中返回FileInputStream。

期望结果 -
当前端调用get-files API时,浏览器应该打开一个文件下载提示。

问题 - 我们不能使用blob.downloadToFile方法,因为它会将文件下载到本地计算机(或API托管的位置),而我们需要一种方法,可以直接在API调用时将文件发送到前端。但是有另一种方法blob.download(),它返回一个OutputStream,这个OutputStream无法在API调用上返回。

所以有没有办法可以将这个OutputStream转换成FileInputStream,而不保存到我们的设备上的实际文件中。

示例代码 -

public ByteArrayOutputStream downloadBlob() throws URISyntaxException, InvalidKeyException, StorageException, IOException {
    String storageConnectionString = "DefaultEndpointsProtocol=https;" + "AccountName=" + accountName + ";"
            + "AccountKey=" + accountKey;

    CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);

    CloudBlobClient blobClient = storageAccount.createCloudBlobClient();

    final CloudBlobContainer container = blobClient.getContainerReference("container name");

    CloudBlockBlob blob = container.getBlockBlobReference("image.PNG");
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    blob.download(outputStream);
    System.out.println("文件已下载");

    return outputStream;
}

注意- 文件可以是任何类型。

英文:

I am working on an API (spring boot). In which i need to return FileInputStream in Response body of get method.

Expected -
When front end call the get-files API, a file download prompt should be open on browser.

Problem - We can't use blob.downloadToFile method, because it will download the file on local machine(or where APIs are hosted) and we need something using which we can send the File directly to front-end on API call.
However there is another method blob.download(), which returns OutputStream which can't be returned on API call.

So is there any way that we can convert that OutputStream to FileInputStream without saving to a actual file on our device.

Example code -

public ByteArrayOutputStream downloadBlob() throws URISyntaxException, InvalidKeyException, StorageException, IOException {
		String storageConnectionString = "DefaultEndpointsProtocol=https;" + "AccountName=" + accountName + ";"
				+ "AccountKey=" + accountKey;

		CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);

		CloudBlobClient blobClient = storageAccount.createCloudBlobClient();

		final CloudBlobContainer container = blobClient.getContainerReference("container name");


		CloudBlockBlob blob = container.getBlockBlobReference("image.PNG");
		ByteArrayOutputStream outputStream =new ByteArrayOutputStream();
		blob.download(outputStream);
		System.out.println("file downloaded");

		return outputStream;
	}

Note- the file can be of any type.

答案1

得分: 3

以下是翻译好的代码部分:

package com.example.demo.controllers;

import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

@RestController
public class FileDownload {
    @GetMapping(path = "/download-file")
    public ResponseEntity<Resource> getFile() {
        String fileName = "Can not find symbol.docx";
        // Azure凭据
        String connection_string = "Azure存储账户的连接字符串";

        BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().connectionString(connection_string).buildClient();

        BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient("容器名称");
        System.out.println(containerClient.getBlobContainerName());

        BlobClient blob = containerClient.getBlobClient(fileName);

        // 创建输出流对象以从Azure Blob接收文件内容。
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        blob.download(outputStream);

        // 将其转换为输入流以返回
        final byte[] bytes = outputStream.toByteArray();
        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
        ByteArrayResource resource = new ByteArrayResource(bytes);
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");

        return ResponseEntity.ok().contentType(MediaType.APPLICATION_OCTET_STREAM)
                .headers(headers)
                .body(resource);
    }
}

注意:以上只是代码的翻译部分,不包括注释内容。

英文:

Here is the solution - After hitting the API in browser, your file will be downloaded in browser -

package com.example.demo.controllers;
import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@RestController
public class FileDownload {
@GetMapping(path=&quot;/download-file&quot;)
public ResponseEntity&lt;Resource&gt; getFile(){
String fileName = &quot;Can not find symbol.docx&quot;;
//azure credentials
String connection_string = &quot;Connection String of storage account on azure&quot;;
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().connectionString(connection_string).buildClient();
BlobContainerClient containerClient= blobServiceClient.getBlobContainerClient(&quot;Container name&quot;);
System.out.println(containerClient.getBlobContainerName());
BlobClient blob = containerClient.getBlobClient(fileName);
//creating an object of output stream to recieve the file&#39;s content from azure blob.
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
blob.download(outputStream);
//converting it to the inputStream to return
final byte[] bytes = outputStream.toByteArray();
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
ByteArrayResource resource = new ByteArrayResource(bytes);
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, &quot;attachment; filename=\&quot;&quot; + fileName + &quot;\&quot;&quot;);
return ResponseEntity.ok().contentType(MediaType.APPLICATION_OCTET_STREAM)
.headers(headers)
.body(resource);
}
}

huangapple
  • 本文由 发表于 2020年8月21日 21:25:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/63523766.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定