Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 如何将OsStr转换为&;[u8]/Vec<;u8>;在窗户上?_String_Rust - Fatal编程技术网

String 如何将OsStr转换为&;[u8]/Vec<;u8>;在窗户上?

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

我正在尝试将原始OS文件名持久化到存储中,因此需要获取
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
    归结为
    和[u8]
    ,因为POSIX函数接受并返回字节字符串
  • 在Windows上,
    OsStr
    可以看作是一个
    &[u16]
    ,因为Win32 Unicode函数接受并返回字符串作为16位单元的数组
由于本机Windows API接受16位“宽字符”1的序列,这就是
OsStr
设计用来存储的序列。虽然
OsStr
可以转换为字节,因为任何东西都可以转换为字节,但这种表示方式没有用处,因为这些字节对用户和系统都没有意义。这就是为什么
OsStr
没有提供在Windows上以字节形式检索内容的方法。但是,它确实提供了在Win32中有用的迭代底层
u16
值的
OsStr::encode_wide()
。在另一个方向上,
OsString::from_wide()
可用于从
u16
值的切片创建
OsString

由您决定持久层将如何处理平台之间的差异。Rust的
OsStr
提供了实现往返所需的工具,但不同平台的代码必然不同。例如,serde通过as
enum 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中可能没有公开