1use std::fs;
2use std::io::{self, Read};
3
4fn read_file(filename: &str) -> io::Result<String> {
5 // 打开一个文件并返回Result
6 let mut file = fs::File::open(filename)?;
7 // 创建一个新的字符串用于保存文件内容
8 let mut contents = String::new();
9 // 读取文件的内容到字符串并返回Result
10 file.read_to_string(&mut contents)?;
11 Ok(contents)
12}
在本例中,我们使用fs::File::open函数打开文件并返回一个Result对象。?运算符用于在调用堆栈中传播错误。如果open函数返回Err变量,它将使函数的其余部分短路,并将Err变量返回给调用者。如果它返回一个Ok变量,它将打开该值并将其赋值给文件。
1use std::fs;
2use std::io::{self, Write};
3
4fn write_file(filename: &str, contents: &str) -> io::Result<()> {
5 // 创建一个新的文件或覆盖已经存在的文件
6 let mut file = fs::File::create(filename)?;
7 // 将字符串的内容写入文件并返回Result
8 file.write_all(contents.as_bytes())?;
9 Ok(())
10}
1use std::io;
2use std::net::{TcpListener, TcpStream};
3use std::thread;
4
5fn handle_client(stream: TcpStream) -> io::Result<()> {
6 // 创建一个缓冲期用于存储接收到的数据
7 let mut buffer = [0; 1024];
8 loop {
9 // 从TCP流中读取数据并返回Result
10 let n = stream.read(&mut buffer)?;
11 if n == 0 {
12 return Ok(());
13 }
14 // 转换缓冲区中的字节为utf8编码的字符串
15 let request = String::from_utf8_lossy(&buffer[..n]);
16 println!("Received request: {}", request);
17
18 let response = "HTTP/1.1 200 OK\r\n\r\nHello, World!";
19 // 将返回信息写入TCP流中并返回Result
20 stream.write_all(response.as_bytes())?;
21 }
22}
23
24fn main() -> io::Result<()> {
25 // 绑定本地8080端口
26 let listener = TcpListener::bind("127.0.0.1:8080")?;
27 println!("Listening on port 8080...");
28 for stream in listener.incoming() {
29 let stream = stream?;
30 println!("New client connected!");
31 thread::spawn(|| {
32 // 生成一个新的线程去处理接收到的数据
33 handle_client(stream).unwrap();
34 });
35 }
36
37 Ok(())
38}
在本例中,我们使用' TcpListener '类型创建一个绑定到本地主机端口8080上的的侦听器。然后我们使用' incoming '方法来迭代传入的连接。对于每个连接,我们生成一个新线程,并调用' handle_client '函数来处理客户端请求。
使用' Result '类型来处理错误。Rust的' Result '类型是一个以一致且可组合的方式处理错误的强大工具。
使用' ?'操作符将错误传播到调用堆栈。“?'操作符使得在发生错误时可以很容易地从函数中提前返回,而不必编写显式的' match '语句。
尽可能使用异步I/O。如Rust的异步运行时“tokio”,它为构建可伸缩的网络应用程序提供了强大而高效的异步运行时。
考虑使用更高级别的库。有许多库可以为常见的I/O和网络任务提供更高级别的抽象,例如HTTP的hyper和PostgreSQL的togio-postgres。这些库可以节省您的时间,并使您的代码更具可读性。