我正在尝试将原始操作系统文件名持久存储,因此我需要获取原始字节数OsStr.
似乎可以调用as_bytes()*nix平台,但这不是在MS Windows上定义的.
是否有可移植的方式转换OsStr为字节?
要点OsStr是它的表示是特定于操作系统的。由于技术原因,实现有些复杂(@Shepmaster 的答案提供了更多细节),但您可以这样想:
OsStr归结为&[u8],因为 POSIX 函数接受并返回字节字符串;OsStr可以被认为是&[u16],因为 Win32 Unicode 函数接受并返回字符串作为 16 位单元的数组。由于本机 Windows API 接受 16 位“宽字符” 1的序列,因此这就是OsStr设计存储的内容。虽然OsStr 可以将 an 转换为字节,因为任何东西都可以转换为字节,但这种表示形式没有用,因为这些字节对用户和系统都没有意义。这就是为什么OsStr不提供在 Windows 上以字节形式检索内容的方法。但是,它确实提供了对 Win32 中有用的基础值OsStr::encode_wide()的迭代。在另一个方向上,可用于从值切片创建一个。u16OsString::from_wide()OsStringu16
由您决定持久层如何处理平台之间的这种差异。Rust提供的是实现往返的OsStr必要工具,但不同平台的代码必然有所不同。例如,serde 通过有效地将as视为来解决差异enum OsString { Unix(Vec<u8>), Windows(Vec<u16>) }。
u16有效 UTF-16 的值对,但仍然可用。这就是为什么无法通过将 Windows 字符串转换为 UTF-8 等方式将其表示为字节的原因。
OsStr在 Rust 1.16 中没有定义的接口来获取Windows 上的字节。OsStr 委托给系统特定代码的实际实现。在 *nix 上,这是一个围绕Vec<u8>;的包装器。在 Windows 上,这是围绕Wtf8Buf. 虽然使用Wtf8Buf实现Vec<u8>,但不会公开该实现细节。有关 WTF-8 的更多详细信息可在其网站上找到,其中包括此引文,重点是我的:
在 Windows(在其 API 中使用可能格式错误的 UTF-16)上,Rust 标准库在内部将 WTF-8 用于操作系统字符串,但不公开 WTF-8 字节序列。
“问题”在于,在不同平台上,将“字符串”传递给操作系统接口时没有统一的“字符串”概念。在 *nix 上,接口通常接受几乎类似于 UTF-8 的内容,但它们不处理嵌入的 NUL 值。在 Windows 上,这取决于您是否调用API的W或A变体,尽管W强烈首选变体。
这变得更加困难,因为库也可能使用与操作系统不同的编码。如果您在 Windows 上使用在 *nix 上创建的 C 库,则尤其如此——它几乎可以保证接受伪 UTF-8 字符串,然后发生某种有损转换以调用正确的底层 API。
Rust 通过提供不透明类型OsStr和OsString.
如果您需要将 an 传递OsStr给接受 UTF-8 数据的函数,则需要将其转换为 a Stringor &str,然后您就可以获取其字节。如果需要将其传递给接受 a 的函数,则LPCWSTR首先需要转换为 a Vec<u16>,然后将指向该缓冲区的指针传递给 Windows API。您可以看到Rust 本身如何做到这一点的示例。
| 归档时间: |
|
| 查看次数: |
1003 次 |
| 最近记录: |