文盘Rust -- 如何把配置文件打包到二进制文件里 | 京东云技术团队

在实际开发中,经常会遇到各种不同的配置文件。通常,程序运行的各种配置从外部读取,以增强应用配置的灵活性。java 生态中的 springboot 提供了这种设计的典范。springboot 的应用程序,默认通过 application.yml 加载配置。默认的 application.yml 文件打进 jar 包,如果想改变程序的行为,可以在jar 包的同级目录下创建 application.yml 文件或者通过参数指定配置文件位置。那么在 rust 生态里有没有办法把默认配置文件打包到二进制文件呢。

我们可以通过 rust-embed 第三方库来实现这一效果。

在实际开发中的典型场景是: 不指定任何配置文件时,使用默认配置文件;当应用程序同级目录下包含配置文件时加载该配置文件。

  • 定义嵌入文件的位置及获取函数

    src/resources/embed_resource.rs 中定义了嵌入文件的位置及获取函数

    rust 复制代码
    use rust_embed::RustEmbed;
    
    #[derive(RustEmbed)]
    #[folder = "src/embedfiles/"]
    struct Asset;
    
    pub fn get_app_default() -> Option {
      Asset::get("./app_default.yml")
    }

    宏定义了嵌入文件的目录 '#[folder = "src/embedfiles/"]',获取文件函数以该目录为根。

  • 使用嵌入文件

    rust 复制代码
    fn main() {
      if Path::new("./app.yml").exists() {
          let contents =
              fs::read_to_string("./app.yml").expect("Read file error!");
          println!("{}", contents);
          return;
      }
      let app = get_app_default().unwrap();
      let f = std::str::from_utf8(app.data.as_ref()).unwrap();
      println!("{}", f);
    }

按照优先级,我们先检查应用同级目录下有没有app.yml文件,如果有就加载,否则加载默认配置文件。我们先前定义的获取嵌入文件的函数会返回rust_embed::EmbeddedFile 的 struct。通过解析该 struct 的 data 成员,获取文件内容。

  • 测试

    为了避免干扰,我们把编译好的应用 mv 到 /tmp 目录

    bash 复制代码
    cargo build
    mv target/debug/embed /tmp

先执行 embed ,可以看到,输出的是默认配置文件的内容;在应用程序同级目录建立 app.yml 文件,随便填写些内容,再执行 embed 则输出的是 app.yml 文件的内容。

源码地址

以上示例在 macos 上编译执行通过,咱们下期见

作者:京东科技 贾世闻

来源:京东云开发者社区

相关推荐
蒸蒸yyyyzwd20 分钟前
cpp对象模型学习笔记1.1-2.8
java·笔记·学习
程序员徐师兄1 小时前
Windows JDK11 下载安装教程,适合新手
java·windows·jdk11 下载安装·jdk11 下载教程
RANCE_atttackkk1 小时前
[Java]实现使用邮箱找回密码的功能
java·开发语言·前端·spring boot·intellij-idea·idea
五岳2 小时前
DTS按业务场景批量迁移阿里云MySQL表实战(下):迁移管理平台设计与实现
java·应用·dts
zhougl9962 小时前
Java 所有关键字及规范分类
java·开发语言
Python 老手3 小时前
Python while 循环 极简核心讲解
java·python·算法
java1234_小锋3 小时前
Java高频面试题:MyISAM索引与InnoDB索引的区别?
java·开发语言
Mr_Xuhhh3 小时前
MySQL函数详解:日期、字符串、数学及其他常用函数
java·数据库·sql
测试开发Kevin4 小时前
小tip:换行符CRLF 和 LF 的区别以及二者在实际项目中的影响
java·开发语言·python
笨手笨脚の4 小时前
Redis: Thread limit exceeded replacing blocked worker
java·redis·forkjoin·thread limit