来自 inputStream 的内容的 HTTP PUT 请求,大小未知,无法在 HttpUrlConnection 中设置 ChunkedStreamingMode
Posted
技术标签:
【中文标题】来自 inputStream 的内容的 HTTP PUT 请求,大小未知,无法在 HttpUrlConnection 中设置 ChunkedStreamingMode【英文标题】:HTTP PUT request by content from inputStream with unknown size and can not set ChunkedStreamingMode in HttpUrlConnection 【发布时间】:2021-07-04 10:21:55 【问题描述】:我正在尝试向 Azure Blob 存储发送 HTTP PUT 请求,但不允许使用 ChunkedStreamingMode。我正在从大小未知的 InputStream 中读取数据。我可以将 PUT Blob 请求分成多个 PUT Block 请求(Azure Blob Storage 提供了一个 PUT BLOCK 操作来存储单个块,最后,我可以将所有块构建到一个 Blob)。在内存中缓冲 1 MiB 并像块一样发送它是一个好的解决方案吗?还是从输入流中读取并保存到本地文件系统中的临时文件中,然后读取文件并将其作为 Block 发送是更好的解决方案?
【问题讨论】:
您可以发布您尝试使用的代码吗?看起来 C# 的 Azure SDK 支持块:***.com/questions/61481720/… 所以在 Java 中也应该可以。 我没有使用 Azure SDK。 我认为 Azure SDK 使用的是 REST API(虽然我并不真正知道它是如何工作的),所以通过查看 Azure SDK 的源代码,您应该能够弄清楚它们的作用。 怎么样?你的问题得到解决了吗?如果您还有其他问题,请告诉我 我已经通过将 InputStream 存储在一个临时文件中来实现它。我没有使用 Azure SDK,所以我自己通过 REST API 实现了它。 【参考方案1】:根据我的理解,您想逐块上传一个大文件。我认为您的两个解决方案都可以工作,我将为您的第二个解决方案提供一些示例代码:将输入流保存为临时文件并逐块上传,只需通过 Azure Blob SDK 尝试以下代码:
import java.time.Duration;
import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
import com.azure.storage.blob.ProgressReceiver;
import com.azure.storage.blob.models.AccessTier;
import com.azure.storage.blob.models.BlobHttpHeaders;
import com.azure.storage.blob.models.BlobRequestConditions;
import com.azure.storage.blob.models.ParallelTransferOptions;
public class StorageTest
public static void main(String[] args)
//skip the process about saving a temp file, just leaving its path
String tempFilePath = "";
String connString = "<azure storage connection string>";
String containerName = "<container name>";
String destBlobName = "<blob name with path>";
BlobClient blobClient = new BlobServiceClientBuilder().connectionString(connString).buildClient()
.getBlobContainerClient(containerName).getBlobClient(destBlobName);
// 1MB per request in case of consuming too much jvm memory while uploading
long blockSize = 1024 * 1024;
ParallelTransferOptions parallelTransferOptions = new ParallelTransferOptions().setBlockSizeLong(blockSize)
// 2 Concurrency requests as max,you can set more than it to accelerate uploading
.setMaxConcurrency(2)
.setProgressReceiver(new ProgressReceiver()
@Override
public void reportProgress(long bytesTransferred)
System.out.println("uploaded:" + bytesTransferred);
);
BlobHttpHeaders headers = new BlobHttpHeaders().setContentLanguage("en-US").setContentType("binary");
blobClient.uploadFromFile(tempFilePath, parallelTransferOptions, headers, null, AccessTier.HOT,
new BlobRequestConditions(), Duration.ofMinutes(30));
我已经测试过,我可以上传一个 5GB 的文件。 如果您还有其他问题,请告诉我。
【讨论】:
以上是关于来自 inputStream 的内容的 HTTP PUT 请求,大小未知,无法在 HttpUrlConnection 中设置 ChunkedStreamingMode的主要内容,如果未能解决你的问题,请参考以下文章
以 InputStream 格式将文本文件从 .Net http 客户端上传到 Java REST API
从来自 java 中 InputStream 的字符串创建 Spark RDD 或数据帧