最近用 rust 写一个小东西时,发现打开文件时总是会提示 permission denied, 记录一下解决过程
我们看这样一段程序
pub fn get_file_buffer(path: &str) -> Vec<u8> {
let mut file = File::open(path).unwrap();
let mut file_buffer: Vec<u8> = Vec::new();
file.read_to_end(&mut file_buffer).unwrap();
return file_buffer;
}
fn main() {
let file_name = "CALD.B";
let file_buffer = get_file_buffer(file_name);
println!("{} file length: {}", file_name, file_buffer.len());
}
这段程序把文件内容读取到一个 vector 中,很简单的逻辑对不对, 但是运行时总是会 panic
thread ‘main’ panicked at ‘called `Result::unwrap()` on an `Err` value: Os { code: 13, kind: PermissionDenied, message: “Permission denied” }’,
CALD.B 这个文件我想之前关注我文章的人大概知道是什么,
我是从另一个目录拷过来的,permission denied 首先我想到的就是文件权限问题,
那么 ls -l
看一下:
-rwxrwxrwx@ 1 user staff 36528 Dec 5 1995 CALD.B
我感觉这个权限没什么问题,这下只能求助于 google 了,但是看了一圈, 也没有什么帮助,重新确认了下程序的运行目录没有问题, 我尝试打开了另一个文件 Cargo.toml
Cargo.toml file length: 234
这个就更奇怪了,赶快看一下 Cargo.toml 的权限
-rw-r–r– 1 user staff 234 Mar 26 16:26 Cargo.toml -rwxrwxrwx@ 1 user staff 36528 Dec 5 1995 CALD.B
这个权限更少,对比之下 CALD.B 那个 @ 就比较明显了,这个 @ 代表什么呢?
搜了一下,这个是扩展属性,可以用 ls -al@
来查看
-rwxrwxrwx@ 1 user staff 36528 Dec 5 1995 CALD.B com.apple.fileutil.PlaceholderData 336
这个 com.apple.fileutil.PlaceholderData 就是两个文件的差别了,
那么我们可以用 xattr -c CALD.B
来清除所有扩展属性,然后再试试运行程序
CALD.B file length: 36528
成功!
原来是因为文件多了一个扩展属性,而我的这个 com.apple.fileutil.PlaceholderData 属性似乎是 onedrive 引入的,这个是后话。