String 如何将OsStr转换为&;[u8]/Vec<;u8>;在窗户上?
我正在尝试将原始OS文件名持久化到存储中,因此需要获取String 如何将OsStr转换为&;[u8]/Vec<;u8>;在窗户上?,string,rust,String,Rust,我正在尝试将原始OS文件名持久化到存储中,因此需要获取OsStr的原始字节 似乎可以在*nix平台上调用,但在MS Windows上没有定义 是否有一种可移植的方式将OsStr转换为字节?在Rust 1.16的Windows上,没有定义用于获取OsStr字节的接口。OsStr的实际实现。在*尼克斯,这是一个;在Windows上,这是一个。虽然Wtf8Buf是用Vec实现的,但该实现细节并未公开。更多关于WTF-8的详细信息,包括以下报价: 在Windows(在其API中使用可能格式不正确的UTF
OsStr
的原始字节
似乎可以在*nix平台上调用,但在MS Windows上没有定义
是否有一种可移植的方式将
OsStr
转换为字节?在Rust 1.16的Windows上,没有定义用于获取OsStr
字节的接口。OsStr
的实际实现。在*尼克斯,这是一个;在Windows上,这是一个。虽然Wtf8Buf
是用Vec
实现的,但该实现细节并未公开。更多关于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
来避免所有这些
如果需要将
OsStr
传递给接受UTF-8数据的函数,则需要将其转换为字符串
或&str
,然后可以获取该字符串的字节。如果需要将其传递给接受LPCWSTR
的函数,则首先需要将其转换为Vec
,然后将指向该缓冲区的指针传递给Windows API。您可以看到。OsStr的要点是,它的表示是特定于操作系统的。由于技术原因,实现有些复杂(提供了更多细节),但您可以这样想:
- 在POSIX系统上,
归结为OsStr
,因为POSIX函数接受并返回字节字符串李>和[u8]
- 在Windows上,
可以看作是一个OsStr
,因为Win32 Unicode函数接受并返回字符串作为16位单元的数组&[u16]
OsStr
设计用来存储的序列。虽然OsStr
可以转换为字节,因为任何东西都可以转换为字节,但这种表示方式没有用处,因为这些字节对用户和系统都没有意义。这就是为什么OsStr
没有提供在Windows上以字节形式检索内容的方法。但是,它确实提供了在Win32中有用的迭代底层u16
值的OsStr::encode_wide()
。在另一个方向上,OsString::from_wide()
可用于从u16
值的切片创建OsString
由您决定持久层将如何处理平台之间的差异。Rust的OsStr
提供了实现往返所需的工具,但不同平台的代码必然不同。例如,serde通过asenum OsString{Unix(Vec),Windows(Vec)}
解决差异
1 Windows范围的字符串有时被描述为UTF-16,因为这是在更高级别上解释它们的方式,但这并不适用于所有操作系统字符串。Windows文件名可以包含无效UTF-16且仍然可用的
u16
值对。这就是为什么不可能通过将Windows字符串转换为UTF-8等方式将其表示为字节。寻求调试帮助的问题(“为什么此代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。见:.@TatsuyukiIshi这个问题有什么不清楚的地方?这与调试无关…>必须包括所需的行为、特定的问题或错误以及复制所需的最短代码it@TatsuyukiIshi没有为windows定义该函数。因为在中不存在。它是特定于操作系统的。我将澄清OP的问题。OsStr本身在内部使用WTF-8(即带有代理的UTF-8),甚至在Windows上,这是一个实现细节。获取原始字节的唯一方法是执行从OsStr到&[u8]的不安全转换,但这不能保证始终有效。IIRC、Windows和Java实际上使用UCS-2。@Shepmaster是的,这是非常正确的,但UCS-2这个术语可能会产生混淆,我想在回答中避免这种混淆。UCS-2已过时,不再被视为Unicode编码(请参阅。它起源于Unicode被限制在BMP上的时代,联合体有充分的理由不鼓励使用它。联合体谨慎地不命名编码UCS-2,更倾向于引用UTF-16和BMP。OsStr
不可能是UTF-8超集以外的任何东西,因为Rust不支持分配零成本转换对于&str
到&Path
,以及&Path
到&OsStr
,因此每个有效的&str
内存表示必须是有效的&OsStr
,这对UCS-2不适用。@Kornel是的,WTF16在Windows内部使用,但在Windows中可能没有公开