use std::io;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
async fn read_file() -> anyhow::Result<()> {
let mut file = tokio::fs::File::open("/Users/putao/code/test/rust/rust-test02/resouces/example.txt").await?;
let mut buffer = vec![];
let _ = file.read_to_end(&mut buffer).await?;
println!("File contents: {:?}", String::from_utf8_lossy(&buffer));
Ok(())
}
async fn read_file_v2() -> anyhow::Result<()> {
let mut file = tokio::fs::File::open("/Users/putao/code/test/rust/rust-test02/resouces/example.txt").await?;
// 定义一个字节缓冲区和一个字符串缓冲区来处理部分读取
let mut buffer = [0; 1024]; // 1 KB 大小的字节缓冲区
let mut content = String::new(); // 字符串缓冲区,用于存储有效的 UTF-8 数据
let mut temp_buffer = Vec::new(); // 临时缓冲区,用于保存部分读取的字节
// 读取并处理文件内容
loop {
let n = file.read(&mut buffer).await?;
if n == 0 {
// 文件读取完毕
break;
}
// 将读取的字节追加到临时缓冲区
temp_buffer.extend_from_slice(&buffer[..n]);
// 尝试将临时缓冲区的数据转化为字符串
// 注意:使用失效前缀来处理不完整的 UTF-8 字符
match std::str::from_utf8(&temp_buffer) {
Ok(valid_str) => {
// 如果所有数据都是有效的 UTF-8 编码, 直接追加到内容缓冲区中
content.push_str(valid_str);
temp_buffer.clear();
}
Err(e) => {
// 从无效数据中提取有效部分
let valid_up_to = e.valid_up_to();
if valid_up_to > 0 {
let valid_bytes = &temp_buffer[..valid_up_to];
content.push_str(std::str::from_utf8(valid_bytes)?);
temp_buffer.drain(..valid_up_to);
} else {
// 无效数据过短,无法确定有效 UTF-8,等待更多数据
break;
}
}
}
}
// 打印已读取的文件内容
println!("File contents: {}", content);
Ok(())
}
async fn write_file() -> anyhow::Result<()> {
// let mut file = OpenOptions::new()
// .append(true) // 以追加模式打开
// .open("example.txt")
// .await?;
let mut file = tokio::fs::File::create("/Users/putao/code/test/rust/rust-test02/resouces/example02.txt").await?;
file.write_all("我是中国人".as_bytes()).await?;
file.flush().await?;
Ok(())
}
#[tokio::main]
async fn main() {
// read_file().await.unwrap();
read_file_v2().await.unwrap();
// write_file().await.unwrap();
// let input = b"Hello \xF0\x90\x80World";
// let output = String::from_utf8_lossy(input);
// println!("{}", output)
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。