file - 在运行时加载资源文件
问题描述
假设我有这个架构:
.
├── Cargo.lock
├── Cargo.toml
├── src/
│ ├── main.rs
├── rsc/
│ ├── file.xml
我想file.xml
在每次运行时加载以填充一些表。为此,我可以写:
use std::fs::File;
use std::path::Path;
fn open<P: AsRef<Path>>(path: P) {
let _ = File::open(path).unwrap();
println!("file opened");
}
fn main() {
open("../rsc/file.xml");
}
但是如果我不从src
.
我可以执行以下操作:
fn main() {
include_str!("../rsc/file.xml");
}
但这将在编译时完成,这意味着更改file.xml
意味着重新编译程序,因此在可维护性方面完全不安全。
我可以看到的另一个选项是将rsc
路径作为参数提供给我的程序,但我发现它有点麻烦,因为这不是一个可选参数,我真的需要知道我的rsc
目录在哪里,而且我知道我的 crate 将具有这种架构。
有什么我看不到的吗?
我看到了这篇文章:如何避免 Rust 中的硬编码值
但我的问题总结在这一部分:
如果您正在部署二进制文件,您可能必须提供一条路径,让您的应用程序可以找到其资源。
并且没有其他的精确度。
解决方案
您可以使用std::env::current_exe()找到二进制文件的路径。您可以使用它来查找二进制文件所在的目录,然后使用它来加载与该目录相关的一些资源。
例如,如果您的资源位于与二进制文件位于同一目录中的目录“rsrc”中:
let mut rsrc_dir = std::env::current_exe()
.expect("Can't find path to executable");
// Directory containing binary
rsrc_dir.pop();
// Subdir relative to binary
rsrc_dir.push("rsrc");
仅当您的二进制文件与它的资源文件一起安装在相对于二进制文件的某个固定位置时,这才有用。请记住,大多数用户不会从 github 克隆您的 crate 并以这种方式运行它 - 典型的安装方法包括:
- 安装它
cargo install
- 使用一些特定于操作系统的包管理器
- 也许下载一个 tar 或 zip 文件并解压缩它
似乎cargo install
目前不处理安装关联的资源文件(尽管有一个开放的错误)。
推荐阅读
- ruby-on-rails - Rails 嵌套表单不更新。strong_params 设置正确
- python - 剪切并保存通过颜色识别的对象
- reactjs - 如何从两个不同的 API 中获取 Object Json 类型中的两个值?
- javascript - 在 Google Cloud Bucket Upload 之前解决 Promise
- sbt - flink 使用流 sql 查询上传作业时的问题
- java - 如何将填充的 JSP 写入文件系统?
- javascript - 我们应该在 Angular Authentication Guards 中使用 Auth API 执行什么身份验证检查?
- mediawiki-api - Mediawiki API:只搜索人名
- javascript - 我必须改变什么才能在 PhoneGap 中运行正常的 Ajax?
- azure - Exchange API Azure - 邮箱访问('full_access_as_app' 是一个主要问题,如何将范围限定到特定邮箱)