You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust编译的可执行文件全局运行时出现“No such file or directory”错误

问题原因

你遇到的问题是相对路径的解析基准错误:

  • 在/opt/motivate目录运行./motivate时,当前工作目录就是/opt/motivate,./data会被解析为/opt/motivate/data,能正确定位文件。
  • 全局输入motivate运行时,当前工作目录是你打开终端的目录(比如/home/yourname),程序会尝试读取/home/yourname/data,自然找不到目标文件,因此抛出"找不到文件"的错误。
解决方案

推荐通过获取可执行文件所在目录的方式构建data路径,这样无论在哪个目录运行程序,都能正确定位到依赖的data目录。

修改motivate函数的路径构建逻辑:

fn motivate() {
    let rand_filename = gen_rand();
    
    // 获取可执行文件的绝对路径
    let exe_path = std::env::current_exe().expect("Failed to get executable path");
    // 提取可执行文件所在的目录
    let exe_dir = exe_path.parent().expect("Failed to get executable directory");
    // 拼接出目标文件的完整路径
    let quotes_path = exe_dir.join("data").join(format!("{}.json", rand_filename));

    // 读取文件内容
    let file_contents_result = fs::read_to_string(&quotes_path);

    match file_contents_result {
        Ok(file_contents) => {
            // 直接反序列化为目标类型,无需先转成Value
            match serde_json::from_str::<Vec<Quote>>(&file_contents) {
                Ok(quotes) => get_quotes(quotes),
                Err(err) => eprintln!("Error parsing JSON: {}", err),
            }
        }
        Err(err) => {
            eprintln!("Error reading file: {}", err);
        }
    }
}
额外代码改进建议
  1. 替换unwrap(),避免程序崩溃:
    原代码中serde_json::from_str(&file_contents).unwrap()会在JSON解析失败时直接panic,换成match或if let处理错误,能让程序更健壮。

  2. 直接反序列化为目标类型:
    无需先解析成Value,可以直接反序列化为Vec<Quote>(假设JSON文件是Quote对象数组),代码更简洁且类型更安全。

  3. 优化错误处理流程:
    可以用?操作符简化错误传递,需要将motivate函数的返回类型改为Result<(), Box<dyn std::error::Error>>,让错误处理更简洁:

    fn motivate() -> Result<(), Box<dyn std::error::Error>> {
        let rand_filename = gen_rand();
        
        let exe_path = std::env::current_exe()?;
        let exe_dir = exe_path.parent().ok_or("Failed to get executable directory")?;
        let quotes_path = exe_dir.join("data").join(format!("{}.json", rand_filename));
    
        let file_contents = fs::read_to_string(&quotes_path)?;
        let quotes: Vec<Quote> = serde_json::from_str(&file_contents)?;
        get_quotes(quotes);
        
        Ok(())
    }
    
    fn main() {
        if let Err(err) = motivate() {
            eprintln!("Error: {}", err);
            std::process::exit(1);
        }
    }
    
  4. 校验文件存在性:
    如果gen_rand()生成的文件名可能不存在,建议在读取前先检查文件是否存在,提前给出更明确的错误提示。

内容的提问来源于stack exchange,提问作者John Philip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 08:05:20