为了能够在将整个 csv 文件转换为 parquet 之前推断通过
/dev/stdin
传递的 csv 文件的模式,我已经实现了一个包装器来缓冲输入并根据板条箱的要求实现Seek
arrow2
.这一切都有效。
但是,在某些情况下不需要此包装器,例如将文件重定向到标准输入时:
my_binary < /dev/stdin
。我只想在真正需要时才使用该包装器。因此,我需要知道我打开的文件是否在 seek
上出错。
我想出的以下方法似乎有效。有没有更好的办法?这是 Rust 的惯用语吗?
fn main() {
let mut file = std::fs::File::open("/dev/stdin").unwrap();
let seekable = match std::io::Seek::rewind(&mut file) {
Ok(_) => true,
Err(_) => false,
};
println!("File is seekable: {:?}", seekable);
}
C 有一个类似的问题,但解决方案似乎并没有转移到 Rust:How to determine if a file descriptor is seekable? - or is this effectively what
file.rewind()
does under the hood?
C 有一个类似的问题,但解决方案似乎并没有转移到 Rust:How to determine if a file descriptor is seekable? - 或者这实际上是 file.rewind() 在幕后所做的事情?
rewind
实际上执行 lseek(fd, 0, SEEK_SET)
,所以它会产生副作用,好吧,倒带(因此得名)fd 的光标。我假设原来使用SEEK_CUR
的原因是为了避免将光标移动到可搜索文件上以获得最大的通用性。
如果您想完全匹配原始问题,您应该使用
seek(SeekFrom::Current(0))
。如果没关系那么rewind
很好。
另外:
match
,只需在倒带结果上调用is_ok
(/搜索)std::io::Seek::rewind(&mut file)
,如果你use std::io::Seek
那么你可以在任何可搜索的对象上调用提供的方法,比如文件所以:
use std::io::{Seek, SeekFrom::Current};
fn main() {
let mut file = std::fs::File::open("/dev/stdin").unwrap();
let seekable = file.seek(Current(0)).is_ok();
println!("File is seekable: {:?}", seekable);
}
完全符合 C 的答案。
尽管在我的 Mac 上它的价值是默认情况下可搜索设备文件。
唯一能让它失败的方法是如果我管道(不重定向):
> ./test
File is seekable: true
> </dev/null ./test
File is seekable: true
> </dev/null cat | ./test
File is seekable: false