rust 的 File 是有魔法吗?

94 天前
 bli22ard
use std::error::Error;
use std::fs::File;
use std::io::{BufRead, BufReader};


fn main() ->Result<(),Box<dyn Error>> {
    let path=r#"C:\Users\0\Downloads\123.txt"#;
    let fd=File::open(path)?;
    let fd_p=&fd;
    let mut br=BufReader::new(fd_p);
    let mut line=String::new();
    br.read_line(&mut line)?;
    println!("{}",line);
    Ok(())
}

以上代码,BufReader::new(fd_p); 可以传入 fd_p 也可以传入 fd 都正常工作,感觉读取文件要改变数据才可以读取吧,比如文件指针位置,这个不可变引用 fd_p 读取是怎么做到的

1929 次点击
所在节点    Rust
10 条回复
Kaleidopink
94 天前
翻一下文档就能发现实现 Read trait 的是 &File, 而不是 File, 所以即便是不可变引用也可以读取. 内部实现则是用了 unsafe.
bli22ard
94 天前
@Kaleidopink File 也有实现 Read trait , 不过实现方式还是用 &File 的实现。 这些其实不是重点,重点是, 为什么读取数据可以是不可变的
nebkad
94 天前
@bli22ard #2

https://doc.rust-lang.org/stable/std/fs/struct.File.html

Note that, although read and write methods require a &mut File, because of the interfaces for Read and Write, the holder of a &File can still modify the file, either through methods that take &File or by retrieving the underlying OS object and modifying the file that way. Additionally, many operating systems allow concurrent modification of files by different processes. Avoid assuming that holding a &File means that the file will not change.
bli22ard
94 天前
@nebkad 搞这个&File 可以读取(引起数据改变)操作比较迷惑,给人的感觉就是不可变突然可以变了
zizon
93 天前
也容易理解吧.实际 fd 的状态是 os 维护的,rust 顶多是个上层 API 调用方.
nebkad
93 天前
@bli22ard 如果你对 std 的设计不是很满意,你的 OS 平台支持你在 Rust 中使用 &mut 语义的话,你自己重新包装一个 File 也不是很难啊
bli22ard
93 天前
@nebkad 自己实现容易吗? 主要是好奇,把&mut 搞为&,依然可以执行看起来"改变"的操作。感觉 5 楼的解释比较合理。对于 rust 来说,File 就是不可变的,变的那部分在 os 维护,读取的位置,缓冲区等等。
nebkad
93 天前
@bli22ard #7

std 的源码是公开的,你甚至都不用下载直接在我发给你的链接开始点两下就看到了。
就算你改成了支持 &mut 语义,如果 OS 不支持独占,难道你还能阻止别的调用者用同样的路径再开一个 File 吗?
PTLin
92 天前
这个属于 api 设计问题,我举个例子。
假如有个文件 test.txt 内容是 asd
```rust
let file1 = OpenOptions::new().write(true).open("test.txt").unwrap();
let file2 = File::open("test.txt").unwrap();

(&file1).write_all(b"zxc").unwrap();
let mut buf = String::new();
(&file2).read_to_string(&mut buf).unwrap();

assert_eq!(&buf, "zxc");
```
两个变量打开了同样的文件,本来 file2 读取出来的东西应该是 asd ,但是由于打开的是一个文件,file1 修改文件后 file2 就读出来 zxc 了,就是有这种副作用,file2 在根本没有操作的情况下改变了内容,这种性质在语言层面没有办法限制。
介于 os 中 file 的这种特性,设计成非要 mut 才能 read write 就失去了意义。
bli22ard
92 天前
@nebkad
@PTLin 感谢 2 位,说明白了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1073713

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX