Java snakeyaml 修改yaml文件保留注释工具类封装

文章介绍了如何使用snakeyaml库在Java中批量修改yaml文件,同时解决读取时丢失注释的问题。作者通过自定义工具类CommentUtils,实现了保留和恢复文件注释的功能,包括读取带注释的行,存储注释信息,在修改后重新填充注释。文章提供了一个示例代码展示如何使用这个工具类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近需要写一个Java代码用来批量修改yaml文件,然后搜了下,发现有一个 snakeyaml 的工具包可以使用。使用的话也比较简单:

    // 读取
    File f = new File("xxx.yaml");
    String s = FileUtils.readFileToString(f, StandardCharsets.UTF_8);
    Yaml yaml = new Yaml();
    LinkedHashMap map = yaml.loadAs(s, LinkedHashMap.class);

    map.put("key", "value");
    // 写入文件
    s = yaml.dump(map);
    FileUtils.writeStringToFile(f, s, StandardCharsets.UTF_8);

使用之后,发现 snakeyaml 读取 yaml 文件后会丢失文件中的注释。 网上搜了一大堆文档后说是 snakeyaml 可以支持处理注释,最后发现也只是处理 java 类的字段上的注释而已。

然后觉得可以自己处理下注释,又在网上翻到有人也做过这样操作。
指路 👉 snakeyaml操作yml文件中注释的处理

但里面的逻辑貌似还存在一些小小问题,于是参考这位老哥的思路,自己优化了下代码:

大致思路:逐行读取文件,遇到存在注释的行则将其与最近的无注释行记录下来。在修改完yaml文件后,再进行替换,将注释替换回来。

具体逻辑参考代码,逻辑比较简单,但考虑的还算比较全面。
(有两点要注意:1.如果 value 用引号包裹并存在# 的话,会被误判,但这个正则貌似有点难写,就没考虑了,我这的yaml没有这个场景; 2. 同样是引号包裹的字符串,重写的时候引号会被去掉。这个暂时也没处理,要处理的话,可能也是用正则替换一下)

工具类代码

maven 依赖:

        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>        
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.SneakyThrows;
import org.apache.commons.io.FileUtils;
<think>好的,我现在需要帮用户找到一个用Python编写读取YAML文件工具类示例。用户提到他们想要一个工具类,可能希望代码结构清晰,可重用,并且安全。首先,我应该回忆一下PyYAML库的使用方法,因为用户提供的引用里提到了yaml.safe_load()和相关的示例。 首先,工具类通常会把功能封装成类的方法,这样方便多次调用和管理配置。我需要确保使用安全的方法加载YAML,比如yaml.safe_load(),避免潜在的安全风险。引用[1]和[3]都提到了使用safe_load来读取文件,这很重要,特别是当处理不可信的YAML文件时。 接下来,工具类可能需要支持不同的使用场景,比如读取文件、处理异常、可能还有写入YAML的功能。引用[3]中的例子展示了加载、修改和保存YAML文件的过程,所以工具类或许可以包含读取和写入的方法。 另外,用户可能希望工具类能够处理文件路径的问题,比如自动检查文件是否存在,或者在读取时指定编码格式。引用[1]和[3]都使用了with open语句,并指定了编码为utf-8,这有助于避免编码错误。因此,在工具类中,应该包含这些错误处理机制。 然后,我需要考虑工具类的结构。通常,这样的工具类可能会有初始化方法接收文件路径,然后提供load和save等方法。例如,类YAMLHandler初始化时传入文件路径,然后调用load_config来读取配置,返回字典;调用save_config来保存修改后的字典回文件。 异常处理也是关键。如果文件不存在,或者YAML格式错误,工具类应该抛出明确的异常,或者返回错误信息。比如在load_config方法中使用try-except块捕获FileNotFoundError和yaml.YAMLError,这样用户能更容易地调试问题。 另外,用户可能关心如何在实际应用中使用这个工具类。比如,读取数据库配置或者API密钥,如引用[4]提到的,将敏感信息封装YAML文件中。工具类需要能够方便地获取这些配置信息,例如通过get方法访问嵌套的键。 现在,我需要整合这些思路,编写一个符合要求的工具类示例。需要包括类定义、初始化方法、加载和保存方法,以及可能的获取配置项的方法。同时,确保代码注释清晰,说明每个部分的作用,这样用户能更容易理解和使用。 最后,根据用户的要求,生成相关问题。这些问题应该围绕工具类的扩展、异常处理、最佳实践和应用场景,帮助用户进一步探索YAML处理的其他方面。</think>以下是一个使用Python编写YAML文件读取工具类的示例,包含安全加载、异常处理和多种应用场景: ### YAML工具类实现 ```python import yaml from pathlib import Path class YAMLHandler: """YAML配置文件处理器 功能: 1. 安全加载YAML配置 2. 支持配置更新和保存 3. 自动处理文件编码和路径校验 """ def __init__(self, file_path: str): """初始化时验证文件路径""" self.file_path = Path(file_path) if not self.file_path.exists(): raise FileNotFoundError(f"YAML文件不存在: {file_path}") def load_config(self) -> dict: """安全加载YAML配置""" try: with open(self.file_path, "r", encoding="utf-8") as f: return yaml.safe_load(f) or {} except yaml.YAMLError as e: raise ValueError(f"YAML解析错误: {str(e)}") from e def save_config(self, config: dict): """保存配置到YAML文件""" with open(self.file_path, "w", encoding="utf-8") as f: yaml.dump(config, f, allow_unicode=True, sort_keys=False) def get(self, key_path: str, default=None): """支持点分符访问嵌套键值""" keys = key_path.split('.') config = self.load_config() current = config for key in keys: if isinstance(current, dict) and key in current: current = current[key] else: return default return current ``` ### 使用示例 ```python # 初始化处理器 handler = YAMLHandler("config.yaml") # 加载完整配置 database_config = handler.load_config().get("database") print(f"数据库端口: {database_config['port']}") # 获取嵌套配置项 host = handler.get("database.connection.host", "localhost") print(f"数据库地址: {host}") # 更新并保存配置 config = handler.load_config() config["logging"]["level"] = "DEBUG" handler.save_config(config) ``` ### 功能说明 1. **安全加载**:使用`yaml.safe_load()`防止代码注入攻击[^1] 2. **编码处理**:强制使用UTF-8编码读取文件[^3] 3. **路径校验**:初始化时自动检查文件存在性 4. **配置访问**:支持点分符访问嵌套字典键值 5. **格式保留**:`sort_keys=False`保持原始键顺序 ### 典型应用场景 1. 读取数据库连接配置(含密码等敏感信息)[^4] 2. 管理多环境配置文件(开发/测试/生产) 3. 存储API端点配置参数[^2] 4. 管理国际化多语言资源文件
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值