我需要写入文件描述符 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
来避免这种情况。
另请参阅:
- 如何在 Rust 中读取特定的原始文件描述符?
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");
}
}