如何在rust中从ascii解码? rust 的 String::from_utf8_lossy() 的类似物是什么?

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

我有以下代码:

fn handle_client(mut stream: TcpStream) -> () {
   let mut buffer = [0; 4096];

   stream.read(&mut buffer).expect("read fail");

   let path_request: Cow<'_, str> = String::from_utf8_lossy(&buffer[..]);

并且我需要从 ASCII 进行解码,所以我想问 ASCII 编码是否存在

String::from_utf8_lossy()
的类似物?

我需要相似的代码:

fn handle_client(mut stream: TcpStream) -> () {
   let mut buffer = [0; 4096];

   stream.read(&mut buffer).expect("read fail");

   let path_request: Cow<'_, str> = String::from_ascii_lossy(&buffer[..]);
rust utf-8 ascii decoding utf
2个回答
3
投票

Rust 中的字符串必须是有效的 UTF-8 序列。

String::from_utf8_lossy
的所有功能都是用 Unicode“替换字符”(�) 替换字节字符串中不是有效 UTF-8 序列的任何部分。

UTF-8 的设计使所有有效的 ASCII 字符串也是有效的 UTF-8 字符串,因此您可以在 ASCII 字符串上使用完全相同的函数。但是,由于它永远不需要替换字符,因此您可以使用

std::str::from_utf8
代替。此函数类似,但处理无效 UTF-8 序列的方式不同:如果遇到无效 UTF-8 序列,它将简单地返回
Err
,而不是分配新字符串并替换替换字符。如果字符串不是有效的 ASCII/UTF-8,则这在您根本不需要检查字符串的情况下是理想的,因为它可以向您发出这种情况的信号,并且因为它永远不会分配 - 如果没有无效的字符串UTF-8 序列,然后它返回一个
&str
,它借用了您给它的
&[u8]

由于您正在从网络套接字读取数据,因此对等方可能会向您发送非 ASCII 数据,您应该通过发回错误信号或关闭连接来妥善处理这些数据。

或者,如果您只是将路径与代码中的一组常量进行匹配,请考虑使用字节字符串常量 (

b"foo"
) 而不是字符串常量 (
"foo"
),然后甚至不需要转换/验证.


顺便说明一下,即使读取的字节数少于 4096 个字节,您也正在使用“full”缓冲区。在您当前的代码中,这将导致字符串具有大量尾随空字符。

read

调用将返回实际读取的字节数。考虑使用该值来获取仅读入缓冲区的内容的切片,如下所示:

let count = stream.read(&mut buffer).expect("read fail");

let path_request: Cow<'_, str> = String::from_utf8_lossy(&buffer[..count]);

path_request

上的类型注释也是不必要的;编译器可以推断它并且没有歧义。

    


0
投票
ascii

,如果您在 @cdhowie 之后需要它。 ascii 的性能大部分与 std 相当/相同。

© www.soinside.com 2019 - 2024. All rights reserved.