Java 来自inputStream的内容的HTTP PUT请求大小未知,无法在HttpUrlConnection中设置ChunkedStreamingMode

Java 来自inputStream的内容的HTTP PUT请求大小未知,无法在HttpUrlConnection中设置ChunkedStreamingMode,java,azure-storage-blobs,azure-blob-storage,Java,Azure Storage Blobs,Azure Blob Storage,我正在尝试向Azure Blob存储发送HTTP PUT请求,但不允许ChunkedStreamingMode。我正在以未知大小读取InputStream。我可以将PUT Blob请求分离为多个PUT Blob请求(Azure Blob存储提供了一个PUT Block操作来存储单个块,最后,我可以将所有块构建为一个Blob)。在内存中缓冲1个MiB,然后像块一样发送,这是一个好的解决方案吗?或者从inputstream中读取并将其保存到本地文件系统中的临时文件中,然后读取文件并将其作为块发送是更

我正在尝试向Azure Blob存储发送HTTP PUT请求,但不允许ChunkedStreamingMode。我正在以未知大小读取InputStream。我可以将PUT Blob请求分离为多个PUT Blob请求(Azure Blob存储提供了一个PUT Block操作来存储单个块,最后,我可以将所有块构建为一个Blob)。在内存中缓冲1个MiB,然后像块一样发送,这是一个好的解决方案吗?或者从inputstream中读取并将其保存到本地文件系统中的临时文件中,然后读取文件并将其作为块发送是更好的解决方案?

根据我的理解,您希望按块上传一个大文件。我认为您的两个解决方案都可以工作,我将为您的第二个解决方案提供一些示例代码:将输入流保存为临时文件并按块上传,只需尝试以下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));

    }

}
import java.time.Duration;
导入com.azure.storage.blob.BlobClient;
导入com.azure.storage.blob.BlobServiceClientBuilder;
导入com.azure.storage.blob.ProgressReceiver;
导入com.azure.storage.blob.models.AccessTier;
导入com.azure.storage.blob.models.BlobHttpHeaders;
导入com.azure.storage.blob.models.BlobRequestConditions;
导入com.azure.storage.blob.models.ParallelTransferOptions;
公共类存储测试{
公共静态void main(字符串[]args){
//跳过保存临时文件的过程,只保留其路径
字符串tempFilePath=“”;
字符串connString=“”;
字符串containerName=“”;
字符串destBlobName=“”;
BlobClient BlobClient=new BlobServiceClientBuilder().connectionString(connString).buildClient()
.getBlobContainerClient(containerName).getBlobClient(destBlobName);
//每次请求1MB,以防上传时占用太多jvm内存
长块大小=1024*1024;
ParallelTransferOptions ParallelTransferOptions=新建ParallelTransferOptions().setBlockSizeLong(块大小)
//2个并发请求作为最大值,您可以设置超过此值以加速上载
.setMaxConcurrency(2)
.setProgressReceiver(新的ProgressReceiver(){
@凌驾
public void reportProgress(long bytesttransferred){
System.out.println(“上传:“+ByTestTransfered”);
}
});
BlobHttpHeaders headers=新的BlobHttpHeaders().setContentLanguage(“en-US”).setContentType(“binary”);
blobClient.uploadFromFile(tempFilePath、parallelTransferOptions、Header、null、AccessTier.HOT、,
新BlobRequestConditions(),持续时间为分钟(30));
}
}
我已经在我这边进行了测试,上传一个5GB的文件对我来说很有效。
如果您还有任何问题,请告诉我。

您可以发布您尝试使用的代码吗?看起来Azure SDK for C#支持块:所以在Java中也应该是可能的。我没有使用Azure SDK。我想Azure SDK使用REST API(尽管我不知道它是如何工作的),所以通过查看Azure SDK的源代码,你应该能够了解它们的功能。进展如何?你的问题解决了吗?如果您有更多问题,请告诉我。我已通过将InputStream存储在临时文件中来实现它。我没有使用Azure SDK,所以我自己用REST API实现了它。