使用Java操作微软 Azure Blob Storage:上传和下载文件

前言

在现代云原生应用开发中,存储和管理大量数据是常见的需求。Azure Blob Storage是微软Azure提供的一个高扩展性、高可用性的对象存储服务,特别适合存储大量非结构化数据,如文本、图片、视频等。本文将介绍如何使用Java SDK上传和下载文件到Azure Blob Storage。

在这里插入图片描述

什么是Azure Blob Storage

Azure Blob Storage是微软Azure云平台提供的对象存储解决方案,用于存储大量非结构化数据。Blob是一种二进制大型对象,也是适用于要以二进制格式存储的任何数据类型的存储选项。它特别适合以下场景:

  • 提供图像或文档给浏览器直接下载
  • 存储文件以供分布式访问
  • 流式传输视频和音频
  • 存储备份、恢复、灾难恢复和存档数据
  • 使用Azure云服务进行分析
    Blob Storage提供了三种类型的资源:
    1.存储账户:所有Azure存储资源的顶级容器
    2.容器:类似于文件系统中的文件夹
    3.Blob:实际存储的数据文件

在这里插入图片描述

准备工作

在开始编码之前,您需要:
1.Azure订阅:如果您没有Azure订阅,可以创建一个免费账户
2.存储账户:在Azure门户中创建一个存储账户
3.获取连接字符串:从Azure门户获取存储账户的连接字符串

在这里插入图片描述

添加依赖项

首先,我们需要在项目中添加Azure Storage Blob SDK依赖。
如果使用Maven,将以下依赖添加到pom.xml文件中:

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-storage-blob</artifactId>
    <version>12.25.0</version>
</dependency>

如果使用Gradle,请在build.gradle文件中添加:

implementation 'com.azure:azure-storage-blob:12.25.0'

实现文件上传和下载功能

1. 基本配置

首先,我们需要获取Azure存储账户的连接字符串和容器名称:

/**
 * AzureBlobUtils
 * @author senfel
 * @version 1.0
 * @date 2025/8/26 18:06
 */
@Slf4j
public class AzureBlobUtils {
    // Azure存储账户连接字符串
    private static final String CONNECTION_STRING = "DefaultEndpointsProtocol=https;AccountName=<your-account-name>;AccountKey=<your-account-key>;EndpointSuffix=<your-endpoint-suffi>";
    // 容器名称
    private static final String CONTAINER_NAME = "your-container-name";
    // BlobServiceClient
    private static final BlobServiceClient BLOB_SERVICE_CLIENT = new BlobServiceClientBuilder()
            .connectionString(CONNECTION_STRING)
            .buildClient();;
    // 容器客户端
    private static final BlobContainerClient CONTAINER_CLIENT = BLOB_SERVICE_CLIENT.getBlobContainerClient(CONTAINER_NAME);
    //构造方法私有
    private AzureBlobUtils(){}
}

2. 上传本地文件

以下方法演示如何将本地文件上传到Azure Blob Storage:

/**
 * 上传文件到Azure Blob Storage
 * @param filePath
 * @param blobName
 * @author senfel
 * @date 2025/8/26 19:23
 * @return void
 */
public static void uploadFileToBlob(String filePath, String blobName) {
    try {
        // 创建容器(如果不存在)
        if (!CONTAINER_CLIENT.exists()) {
            CONTAINER_CLIENT.create();
        }
        // 获取Blob客户端
        BlobClient blobClient = CONTAINER_CLIENT.getBlobClient(blobName);

        // 上传文件
        blobClient.uploadFromFile(filePath, true);
        log.error( "文件已成功上传到Azure Blob Storage:{}",blobName);
    } catch (Exception e) {
        log.error("上传文件时发生错误:{},详细错误信息:",e.getMessage(),e);
    }
}

3. 上传CSV内容字符串

有时候,我们可能需要直接上传CSV格式的字符串内容,而不是本地文件:

/**
 * 上传CSV内容字符串到Azure Blob Storage
 * @param content
 * @param blobName
 * @author senfel
 * @date 2025/8/26 19:24
 * @return
 */
public static void uploadCsvContentToBlob(String content, String blobName) {
    try {
        // 创建容器(如果不存在)
        if (!CONTAINER_CLIENT.exists()) {
            CONTAINER_CLIENT.create();
        }
        // 获取Blob客户端
        BlobClient blobClient = CONTAINER_CLIENT.getBlobClient(blobName);
        // 将字符串内容转换为输入流
        ByteArrayInputStream dataStream = new ByteArrayInputStream(content.getBytes());
        // 上传数据
        blobClient.upload(dataStream, content.length());
        log.error("CSV内容已上传到Azure Blob Storage:{} ", blobName);
    } catch (Exception e) {
        log.error("上传CSV内容时发生错误:{},详细错误信息:" , e.getMessage(),e);
    }
}

4. 下载文件

以下方法演示如何从Azure Blob Storage下载文件到本地:

/**
 * 从Azure Blob Storage下载文件到本地
 * @param blobName
 * @param localFilePath
 * @author senfel
 * @date 2025/8/26 19:28
 * @return void
 */
public static void downloadFromBlob(String blobName, String localFilePath) {
    try {
        // 检查容器是否存在
        if (!CONTAINER_CLIENT.exists()) {
            log.error("容器不存在:{} ", CONTAINER_NAME);
            return;
        }
        // 获取Blob客户端
        BlobClient blobClient = CONTAINER_CLIENT.getBlobClient(blobName);
        // 检查Blob是否存在
        if (!blobClient.exists()) {
            log.error("文件不存在:{} ", blobName);
            return;
        }

        // 下载文件到本地路径
        blobClient.downloadToFile(localFilePath, true);
        log.info("文件已下载到本地:{} ", localFilePath);
    } catch (Exception e) {
        log.error("下载文件时发生错误:{},详细错误信息:" , e.getMessage(),e);
    }
}

5. 获取CSV文件内容为字符串

有时候我们可能需要直接获取CSV文件的内容为字符串,而不是保存到本地文件:

/**
 * 获取Azure Blob Storage中CSV文件的内容为字符串
 * @param blobName
 * @author senfel
 * @date 2025/8/26 19:30
 * @return java.lang.String
 */
public static String getContentFromBlob(String blobName) {
    try {
        // 检查容器是否存在
        if (!CONTAINER_CLIENT.exists()) {
            log.error("容器不存在:{}" , CONTAINER_NAME);
            return null;
        }

        // 获取Blob客户端
        BlobClient blobClient = CONTAINER_CLIENT.getBlobClient(blobName);

        // 检查Blob是否存在
        if (!blobClient.exists()) {
            log.error("文件不存在:{}" , blobName);
            return null;
        }
        // 读取Blob内容到字节数组
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        blobClient.download(outputStream);
        // 将字节数组转换为字符串
        String content = outputStream.toString();
        outputStream.close();
        log.error("获取CSV文件内容:{}" , blobName);
        return content;
    } catch (Exception e) {
        log.error("获取CSV文件内容时发生错误:{},详细错误信息:" , e.getMessage(),e);
        return null;
    }
}

6. 列出容器中的所有文件

以下方法可以列出容器中的所有文件:

/**
 * 列出容器中的所有文件
 * @author senfel
 * @date 2025/8/26 19:35
 * @return void
 */
public static void listBlobs() {
    try {
        // 检查容器是否存在
        if (!CONTAINER_CLIENT.exists()) {
            log.error("容器不存在:{} ",CONTAINER_NAME);
            return;
        }
        // 列出所有Blob
        log.error("容器中的文件列表:{} ",CONTAINER_NAME);
        for (BlobItem blobItem : CONTAINER_CLIENT.listBlobs()) {
            // 只显示CSV文件
            if (blobItem.getName().endsWith(".csv")) {
                System.out.println("- " + blobItem.getName());
            }
        }
    } catch (Exception e) {
        log.error("列出文件时发生错误:{},详细错误信息:" , e.getMessage(),e);
    }
}

7. 删除文件

以下方法可以删除容器中的文件:

/**
 * 删除容器中的文件
 * @param blobName
 * @author senfel
 * @date 2025/8/26 19:40
 * @return void
 */
public static void deleteFromBlob(String blobName) {
    try {
        // 检查容器是否存在
        if (!CONTAINER_CLIENT.exists()) {
            log.error("容器不存在:{} " ,CONTAINER_NAME);
            return;
        }
        // 获取Blob客户端
        BlobClient blobClient = CONTAINER_CLIENT.getBlobClient(blobName);
        // 检查Blob是否存在
        if (!blobClient.exists()) {
            log.error("文件不存在:{} " ,blobName);
            return;
        }
        // 删除Blob
        blobClient.delete();
        log.info("文件已删除:{} " ,blobName);
    } catch (Exception e) {
        log.error("删除文件时发生错误:{},详细错误信息:" , e.getMessage(),e);
    }
}

8. 完整工具类

以下是完整的示例程序,演示如何使用上述方法:

/**
 * AzureBlobUtils
 * @author senfel
 * @version 1.0
 * @date 2025/8/26 18:06
 */
@Slf4j
public class AzureBlobUtils {
    // Azure存储账户连接字符串
    private static final String CONNECTION_STRING = "DefaultEndpointsProtocol=https;AccountName=<your-account-name>;AccountKey=<your-account-key>;EndpointSuffix=<your-endpoint-suffi>";
    // 容器名称
    private static final String CONTAINER_NAME = "your-container-name";
    // BlobServiceClient
    private static final BlobServiceClient BLOB_SERVICE_CLIENT = new BlobServiceClientBuilder()
            .connectionString(CONNECTION_STRING)
            .buildClient();;
    // 容器客户端
    private static final BlobContainerClient CONTAINER_CLIENT = BLOB_SERVICE_CLIENT.getBlobContainerClient(CONTAINER_NAME);
    //构造方法私有
    private AzureBlobUtils(){}

    /**
     * 上传文件到Azure Blob Storage
     * @param filePath
     * @param blobName
     * @author senfel
     * @date 2025/8/26 19:23
     * @return void
     */
    public static void uploadFileToBlob(String filePath, String blobName) {
        try {
            // 创建容器(如果不存在)
            if (!CONTAINER_CLIENT.exists()) {
                CONTAINER_CLIENT.create();
            }
            // 获取Blob客户端
            BlobClient blobClient = CONTAINER_CLIENT.getBlobClient(blobName);

            // 上传文件
            blobClient.uploadFromFile(filePath, true);
            log.error( "文件已成功上传到Azure Blob Storage:{}",blobName);
        } catch (Exception e) {
            log.error("上传文件时发生错误:{},详细错误信息:",e.getMessage(),e);
        }
    }

    /**
     * 上传CSV内容字符串到Azure Blob Storage
     * @param content
     * @param blobName
     * @author senfel
     * @date 2025/8/26 19:24
     * @return
     */
    public static void uploadCsvContentToBlob(String content, String blobName) {
        try {
            // 创建容器(如果不存在)
            if (!CONTAINER_CLIENT.exists()) {
                CONTAINER_CLIENT.create();
            }
            // 获取Blob客户端
            BlobClient blobClient = CONTAINER_CLIENT.getBlobClient(blobName);
            // 将字符串内容转换为输入流
            ByteArrayInputStream dataStream = new ByteArrayInputStream(content.getBytes());
            // 上传数据
            blobClient.upload(dataStream, content.length());
            log.error("CSV内容已上传到Azure Blob Storage:{} ", blobName);
        } catch (Exception e) {
            log.error("上传CSV内容时发生错误:{},详细错误信息:" , e.getMessage(),e);
        }
    }

    /**
     * 从Azure Blob Storage下载文件到本地
     * @param blobName
     * @param localFilePath
     * @author senfel
     * @date 2025/8/26 19:28
     * @return void
     */
    public static void downloadFromBlob(String blobName, String localFilePath) {
        try {
            // 检查容器是否存在
            if (!CONTAINER_CLIENT.exists()) {
                log.error("容器不存在:{} ", CONTAINER_NAME);
                return;
            }
            // 获取Blob客户端
            BlobClient blobClient = CONTAINER_CLIENT.getBlobClient(blobName);
            // 检查Blob是否存在
            if (!blobClient.exists()) {
                log.error("文件不存在:{} ", blobName);
                return;
            }

            // 下载文件到本地路径
            blobClient.downloadToFile(localFilePath, true);
            log.info("文件已下载到本地:{} ", localFilePath);
        } catch (Exception e) {
            log.error("下载文件时发生错误:{},详细错误信息:" , e.getMessage(),e);
        }
    }

    /**
     * 获取Azure Blob Storage中CSV文件的内容为字符串
     * @param blobName
     * @author senfel
     * @date 2025/8/26 19:30
     * @return java.lang.String
     */
    public static String getContentFromBlob(String blobName) {
        try {
            // 检查容器是否存在
            if (!CONTAINER_CLIENT.exists()) {
                log.error("容器不存在:{}" , CONTAINER_NAME);
                return null;
            }

            // 获取Blob客户端
            BlobClient blobClient = CONTAINER_CLIENT.getBlobClient(blobName);

            // 检查Blob是否存在
            if (!blobClient.exists()) {
                log.error("文件不存在:{}" , blobName);
                return null;
            }
            // 读取Blob内容到字节数组
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            blobClient.download(outputStream);
            // 将字节数组转换为字符串
            String content = outputStream.toString();
            outputStream.close();
            log.error("获取CSV文件内容:{}" , blobName);
            return content;
        } catch (Exception e) {
            log.error("获取CSV文件内容时发生错误:{},详细错误信息:" , e.getMessage(),e);
            return null;
        }
    }

    /**
     * 列出容器中的所有文件
     * @author senfel
     * @date 2025/8/26 19:35
     * @return void
     */
    public static void listBlobs() {
        try {
            // 检查容器是否存在
            if (!CONTAINER_CLIENT.exists()) {
                log.error("容器不存在:{} ",CONTAINER_NAME);
                return;
            }
            // 列出所有Blob
            log.error("容器中的文件列表:{} ",CONTAINER_NAME);
            for (BlobItem blobItem : CONTAINER_CLIENT.listBlobs()) {
                // 只显示CSV文件
                if (blobItem.getName().endsWith(".csv")) {
                    System.out.println("- " + blobItem.getName());
                }
            }
        } catch (Exception e) {
            log.error("列出文件时发生错误:{},详细错误信息:" , e.getMessage(),e);
        }
    }

    /**
     * 删除容器中的文件
     * @param blobName
     * @author senfel
     * @date 2025/8/26 19:40
     * @return void
     */
    public static void deleteFromBlob(String blobName) {
        try {
            // 检查容器是否存在
            if (!CONTAINER_CLIENT.exists()) {
                log.error("容器不存在:{} " ,CONTAINER_NAME);
                return;
            }
            // 获取Blob客户端
            BlobClient blobClient = CONTAINER_CLIENT.getBlobClient(blobName);
            // 检查Blob是否存在
            if (!blobClient.exists()) {
                log.error("文件不存在:{} " ,blobName);
                return;
            }
            // 删除Blob
            blobClient.delete();
            log.info("文件已删除:{} " ,blobName);
        } catch (Exception e) {
            log.error("删除文件时发生错误:{},详细错误信息:" , e.getMessage(),e);
        }
    }

    /**
     * test
     * @author senfel
     * @date 2025/8/26 19:55
     * @return void
     */
    public static void main(String[] args) {
        // 示例1: 上传本地文件
        //uploadFileToBlob("C:\\Users\\user\\Desktop\\test.csv", "test.csv");

        // 示例2: 上传内容字符串
        /*String contentStr = "name,age,city\nJohn,25,New York\nJane,30,London\n";
        uploadCsvContentToBlob(contentStr, "sample-data.csv");*/

        // 示例3: 列出所有文件
        //listBlobs();

        // 示例4: 下载文件
        //downloadFromBlob("test.csv", "C:\\Users\\user\\Desktop\\test2.csv");

        // 示例5: 获取文件内容为字符串
        String content = getContentFromBlob("sample-data.csv");
        if (content != null) {
            //文件内容:
            //name,age,city
            //John,25,New York
            //Jane,30,London
            System.out.println("文件内容:\n" + content);
        }

        // 示例6: 删除文件
        //deleteFromBlob("sample-data.csv");
    }
}

总结

本文介绍了如何使用Java SDK上传和下载文件到Azure Blob Storage,并提供了文件的增删改查工具类。总的来说,Azure Blob Storage还是比较好用的,也是提供了高可用性和可扩展性,非常适合存储大量非结构化数据。通过使用Azure Storage SDK for Java,我们可以轻松地将数据上传到云存储,从而构建更加可靠和可扩展的应用程序。在实际项目中,我们可以根据具体需求扩展这些示例,添加更多功能如进度监控、错误恢复、批量操作等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小沈同学呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值