如何从 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 存储中读取所有文件

如何使用数据工厂将数据从 Azure Blob 存储增量加载到 Azure SQL 数据库?

如何从 azure blob 存储下载文件

如何从 Azure 容器中的 blob 中获取所有 URL 的列表?