我需要写入文件描述符3.我一直在搜索它,但文档很差。我发现的唯一的事情是使用libc
库和fdopen
方法,但我没有找到任何关于如何使用它或写在上面的例子。
任何人都可以给我一个写入Rust文件描述符的例子吗?
您可以使用FromRawFd
从特定文件描述符创建File
,但仅限于类UNIX操作系统:
use std::{
fs::File,
io::{self, Write},
os::unix::io::FromRawFd,
};
fn main() -> io::Result<()> {
let mut f = unsafe { File::from_raw_fd(3) };
write!(&mut f, "Hello, world!")?;
Ok(())
}
$ target/debug/example 3> /tmp/output
$ cat /tmp/output
Hello, world!
from_raw_fd
不安全,因为无法保证文件描述符有效或者实际上负责该文件描述符。
创建的File
将承担文件描述符的所有权:当File
超出范围时,文件描述符将被关闭。您可以使用IntoRawFd
或mem::forget
来避免这种情况。
也可以看看:
libc
crate是“只是”C和Rust之间接口的包装库所以要知道如何使用函数,应该阅读C函数的手册,有很多来源,这里有一个fdopen()
:
fdopen()
函数将流与现有文件描述符fd
相关联。流的模式(值"r"
,"r+"
,"w"
,"w+"
,"a"
,"a+"
中的一个)必须与文件描述符的模式兼容。新流的文件位置指示符设置为属于fd
的文件位置指示符,并清除错误和文件结束指示符。模式"w"
或"w+"
不会导致文件截断。文件描述符不是重复的,并且在fdopen()
创建的流关闭时将关闭。将fdopen()
应用于共享内存对象的结果是未定义的。
基本用途是这样的:
use libc::fdopen;
use std::ffi::CString;
fn main() {
let mode = CString::new("w").unwrap();
unsafe {
let _ = fdopen(3, mode.as_ptr());
}
}
要使用它,你可以使用fwrite()
:
函数
fwrite()
将nmemb
数据元素(每个大小字节长)写入流指向的流,从ptr
给出的位置获取它们。
那么,完整的例子:
use libc::{c_void, fdopen, fwrite};
use std::ffi::CString;
fn main() {
let mode = CString::new("w").unwrap();
let file = unsafe {
let file = fdopen(3, mode.as_ptr());
if file.is_null() {
panic!("can't open file");
}
file
};
let welcome = "Hello world!";
let result = unsafe { fwrite(welcome.as_ptr() as *const c_void, 1, welcome.len(), file) };
if result != welcome.len() {
panic!("write not successful");
}
}