如何写入Rust的特定原始文件描述符?

问题描述 投票:1回答:2

我需要写入文件描述符3.我一直在搜索它,但文档很差。我发现的唯一的事情是使用libc库和fdopen方法,但我没有找到任何关于如何使用它或写在上面的例子。

任何人都可以给我一个写入Rust文件描述符的例子吗?

unix io rust file-descriptor
2个回答
7
投票

您可以使用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超出范围时,文件描述符将被关闭。您可以使用IntoRawFdmem::forget来避免这种情况。

也可以看看:


1
投票

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");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.