如何从 Java 中的 Azure Blob 存储中读取文件夹结构为“dir1 / dir2 / dir3 / 20210301-20210331”的 csv 文件?
Posted
技术标签:
【中文标题】如何从 Java 中的 Azure Blob 存储中读取文件夹结构为“dir1 / dir2 / dir3 / 20210301-20210331”的 csv 文件?【英文标题】:How to read the csv files from Azure Blob Storage in Java with folder structure as 'dir1 / dir2 / dir3 / 20210301-20210331'? 【发布时间】:2021-07-08 20:45:05 【问题描述】:我已经在我的 azure blob 存储帐户中安排了导出,它是一个 monhtly 运行,它在 dir1 / dir2 / dir3 / StartDateOfMonth-EndDateOfMonth
之类的文件夹下创建一个 csv 文件。
我有以下事情要做。
1- 我想在java中读取这个文件而不下载它。
2 - 想要使用 Spring Batch 主从模式并行读取。
面临的问题:-
1- 我没有使用下面的行获得绝对路径
CloudAppendBlob cloudAppendBlob= container.getAppendBlobReference("blob_file_name");
log.info("cloudAppendBlob.getUri().getPath() = ",cloudAppendBlob.getUri().getPath());
2- 如果有人帮助我如何在 Spring Batch 主从模式中做到这一点,那对我来说将非常有帮助。 [我知道的普通 Spring Batch 主从模式让 CSV 从本地路径读取文件]
【问题讨论】:
@MahmoudBenHassine,我刚刚将我的 blob 文件 [存在于我的 Azure Blob 存储帐户中] 的硬编码路径提供给 UrlResource。 @MahmoudBenHassine UrlResource resource = new UrlResource("containerName.blob.core.windows.net/DirectoryName/dir1/dir2/…); 我有一个错误Caused by: java.lang.IllegalStateException: Input resource must exist (reader is in 'strict' mode): URL
【参考方案1】:
1- 我想在java中读取这个文件而不下载它。
您可以使用 Spring Batch 提供的文件项读取器(平面文件、xml 文件、json 文件等)之一,并使用org.springframework.core.io.UrlResource
对其进行配置。这是一个简单的例子:
UrlResource resource = new UrlResource("remote/url/to/your/file");
FlatFileItemReader<String> itemReader = new FlatFileItemReaderBuilder<String>()
.resource(resource)
// set other properties
.build();
2 - 想要使用 Spring Batch 主从模式并行读取。
您可以使用 Spring Batch 提供的远程分区技术,其中每个文件都在一个分区中处理(即每个文件一个工作人员)。 Spring Batch 提供了专门为此设计的MultiResourcePartitioner。您可以在Partitioning 部分和完整示例here 中找到更多详细信息。
【讨论】:
UrlResource resource = new UrlResource("containerName.blob.core.windows.net/DirectoryName/dir1/dir2/...); 我有一个错误原因:java.lang.IllegalStateException:输入资源必须存在(阅读器处于“严格”模式):URL 你能建议我如何使用它吗? 这不是 URL。 URL 应符合java.net.URL【参考方案2】:我找到了一种从 Java 中的 Azure Blob 存储下载 .csv 文件的解决方案,其文件夹结构为“dir1 / dir2 / dir3 / StartDateOfMonth-EndDateOfMonth”
@Override
public List listBlobs(String containerName)
List uris = new ArrayList<>();
String fileName=null;
try
CloudBlobContainer container = cloudBlobClient.getContainerReference(containerName);
Iterable<ListBlobItem> blobs = container.listBlobs("$Directory", true); //for $Directory please find screenshot I have given below. this is the name that you provide during the creation of Export in your Azure Storage account
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().connectionString(environment.getProperty("azure.storage.ConnectionString")).buildClient();
BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(containerName);
FileOutputStream fout = null;
for (ListBlobItem fileBlob : blobs)
log.info("fileBlob instanceof CloudBlob = ",fileBlob instanceof CloudBlob);
if (fileBlob instanceof CloudBlob)
CloudBlob cloudBlob = (CloudBlob) fileBlob;
uris.add(cloudBlob.getName());
log.info("File Name is = ", cloudBlob.getName());
BlobClient blobClient = containerClient.getBlobClient(cloudBlob.getName());
System.out.println(blobClient.getBlobUrl());
System.out.println(blobClient.getBlobUrl().trim());
if (blobClient.exists())
Path p = Paths.get(cloudBlob.getName());
String file = p.getFileName().toString();
String directory = p.getParent().toString();
log.info("Downloading Blob File = from Directory ",file,directory);
File dir = new File("$LOCAL_PATH"+directory);
dir.mkdirs();
fout = new FileOutputStream("$LOCAL_PATH" + cloudBlob.getName());
blobClient.download(fout);
CloudAppendBlob cloudAppendBlob= container.getAppendBlobReference(cloudBlob.getName());
uris.add(cloudAppendBlob.getUri().toURL());
log.info("cloudAppendBlob.getUri().getPath() = ",cloudAppendBlob.getUri().toURL());
for (ListBlobItem blobItem : container.listBlobs())
uris.add(blobItem.getUri().toURL());
//System.out.println("blobItem.getUri().getPath()= "+blobItem.getUri().getPath());
catch (StorageException e)
e.printStackTrace();
catch (URISyntaxException e)
e.printStackTrace();
catch (FileNotFoundException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
return uris;
此代码将下载所有子目录中的所有文件,要从月份的特定目录下载,您可以为目录名称添加日期匹配检查。
【讨论】:
以上是关于如何从 Java 中的 Azure Blob 存储中读取文件夹结构为“dir1 / dir2 / dir3 / 20210301-20210331”的 csv 文件?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 C# 中的 Azure.Storage.Blobs 从 Azure 存储 Blob 以 ByteArray 格式获取文件
如何将 AppendBlob/大于 4mb 限制的文件上传到 Java 中的 Azure 存储/Blob?
如何从 C# Core 中的 azure blob 存储中读取所有文件