我试图将原始OS文件名持久化到存储中,所以我需要获得OsStr的原始字节.

在*nix平台上调用as_bytes()似乎是可能的,但在MS Windows上没有定义.

有没有一种将OsStr字节转换成字节的便携式方法?

推荐答案

OsStr的意义在于,它的表现形式是特定于操作系统的.由于技术原因,实现有些复杂(@Shepmaster's answer提供了更多细节),但您可以这样想:

  • 在POSIX系统上,OsStr归结为&[u8],因为POSIX函数接受并返回字节字符串;
  • 在Windows上,OsStr可以被认为是&[u16],因为Win32 Unicode函数接受并返回字符串作为16位单元的array.

由于本机Windows API接受16位"宽字符"序列1,这就是OsStr的设计目的.由于任何东西都可以转换为字节,所以OsStr字节可以转换为字节,但这种表示方式没有用处,因为这些字节对用户和系统都没有意义.这就是为什么OsStr没有提供在Windows上以字节形式检索内容的方法.然而,它确实提供了OsStr::encode_wide(),可以迭代底层的u16个值,这些值在Win32中很有用.在另一个方向上,OsString::from_wide()可用于从u16个值的切片创建OsString.

由您决定持久层将如何处理平台之间的这种差异.Rust's OsStr提供的是实现往返所需的tools,但不同平台的代码必然不同.例如,serde将差值effectively treating解析为enum OsString { Unix(Vec<u8>), Windows(Vec<u16>) }.


1 Windows wide character strings are sometimes described as UTF-16 because that is how they are interpreted at a higher level, but this is not correct for all OS strings. A Windows file name can contain pairs of u16 values that are not valid UTF-16, and still be usable. This is why it's not possible to represent Windows strings as bytes by e.g. converting them to UTF-8.

Rust相关问答推荐

为什么`Vec i64`的和不知道是`Option i64`?

在不重写/专门化整个函数的情况下添加单个匹配手臂到特征的方法?

如何格式化传入Rust中mysql crate的Pool::new的字符串

你是如何在铁 rust 一侧的金牛座获得应用程序版本的?

在自定义序列化程序中复制serde(With)的行为

使用Box优化可选的已知长度数组的内存分配

当T不执行Copy时,如何返回Arc Mutex T后面的值?

是否提供Bundle 在可执行文件中的warp中的静态文件?

这是什么:`impl Trait for T {}`?

为什么 Rust 创建的 f32 小于 f32::MIN_POSITIVE?

为什么切片时需要参考?

在 Bevy 项目中为 TextureAtlas 精灵实施 NearestNeighbor 的正确方法是什么?

在每个循环迭代中删除borrow

是否可以在 Rust 中的特定字符上实现特征?

如何使返回 XMLError 的方法与 anyhow::Error 兼容?

Rust 异步和 AsRef 未被发送

将 (T, ()) 转换为 T 安全吗?

需要括号的宏调用中的不必要的括号警告 - 这是编写宏的糟糕方法吗?

在 Rust 中有条件地导入?

为什么在使用 self 时会消耗 struct 而在解构时不会?