如何解决Rust CLI程序通过环境变量调用时的文件路径问题?
解决Rust CLI程序跨路径调用时的文件查找问题
问题根源出在你拼接路径的代码:
"./".to_owned() + file
这个操作会强制给用户输入的路径前缀加上./,哪怕用户传的是绝对路径也会被破坏。比如用户输入C:\docs\test.txt,拼接后变成./C:\docs\test.txt,这是完全无效的路径,自然找不到文件。而且./代表的是你执行CLI程序时所在的当前工作目录,不是可执行文件本身的目录,这就是为什么只有在可执行文件目录下调用才能正常运行的原因。
解决方法
直接使用用户传入的原始路径,不要添加多余的./前缀:
修改后的完整代码:
use std::env; use std::fs; fn main() { let args: Vec<String> = env::args().collect(); // 增加参数检查,避免用户不传参数导致程序崩溃 if args.len() < 2 { eprintln!("请传入要读取的文件路径"); std::process::exit(1); } let file = &args[1]; let file_content = fs::read_to_string(file) .expect("无法找到指定文件或读取失败"); println!("文件内容:{}\n", file_content); // 原代码中变量未使用,改为匿名变量避免编译警告 let _ = std::io::stdin().read_line(&mut String::new()).unwrap(); }
额外说明
- 当用户传入相对路径时,它默认就是相对于你执行CLI程序时的当前工作目录,不需要额外添加
./ - 如果你的需求是读取相对于可执行文件所在目录的文件,那需要先获取可执行文件的路径,再拼接目标文件路径,示例代码如下:
use std::env; use std::fs; use std::path::PathBuf; fn main() { let args: Vec<String> = env::args().collect(); if args.len() < 2 { eprintln!("请传入要读取的文件路径"); std::process::exit(1); } // 获取可执行文件所在目录 let exe_path = env::current_exe().expect("无法获取可执行文件路径"); let exe_dir = exe_path.parent().expect("无法获取可执行文件所在目录"); // 拼接目标文件路径(相对于可执行文件目录) let file_path = exe_dir.join(&args[1]); let file_content = fs::read_to_string(file_path) .expect("无法找到指定文件或读取失败"); println!("文件内容:{}\n", file_content); let _ = std::io::stdin().read_line(&mut String::new()).unwrap(); }
内容的提问来源于stack exchange,提问作者beginner
相关产品推荐
相关产品推荐

