我正在开发一个SMTP库,它使用缓冲的阅读器读取网络上的线路.
我想要一种不错的,安全的方式从网络中读取数据,而不依赖于Rust内部,以确保代码按预期工作.具体来说,我想知道Read特性是否保证读取的数据Read::read被附加到作为参数传递的缓冲区而不是完全覆盖缓冲区.
目前,我使用aRange来确保不依赖于Rust内部,而不会覆盖现有数据.
但是,鉴于Rust 曾经有一个很好的方法来做我想要的,我想知道当前的代码是否可以改进,也可能删除unsafe块.
不,它不保证:
use std::io::prelude::*;
use std::str;
fn main() {
let mut source1 = "hello, world!".as_bytes();
let mut source2 = "moo".as_bytes();
let mut dest = [0; 128];
source1.read(&mut dest).unwrap();
source2.read(&mut dest).unwrap();
let s = str::from_utf8(&dest[..16]).unwrap();
println!("{:?}", s)
}
Run Code Online (Sandbox Code Playgroud)
这打印
"moolo, world!\u{0}\u{0}\u{0}"
Run Code Online (Sandbox Code Playgroud)
具体来说,它完全基于类型签名不能做你想要的:
fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
Run Code Online (Sandbox Code Playgroud)
该read方法可以访问的所有内容都是您的可变切片 - 无处存储诸如"您在缓冲区中的距离"等信息.此外,您不允许"扩展"具有更多元素的可变切片 - 您只能改变切片中的值.
对于您的特定情况,您可能需要查看BufRead::read_until.这是一个经过严格测试的例子:
use std::io::{BufRead,BufReader};
use std::str;
fn main() {
let source1 = "header 1\r\nheader 2\r\n".as_bytes();
let mut reader = BufReader::new(source1);
let mut buf = vec![];
buf.reserve(128); // Maybe more efficient?
loop {
match reader.read_until(b'\n', &mut buf) {
Ok(0) => break,
Ok(_) => {},
Err(_) => panic!("Handle errors"),
}
if buf.len() < 2 { continue }
if buf[buf.len() - 2] == b'\r' {
{
let s = str::from_utf8(&buf).unwrap();
println!("Got a header {:?}", s);
}
buf.clear();
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
67 次 |
| 最近记录: |