0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

AsyncRead和AsyncWrite 模塊進(jìn)階用法示例

科技綠洲 ? 來源:TinyZ ? 作者:TinyZ ? 2023-09-20 11:41 ? 次閱讀

Rust 語言是一門高性能、安全、并發(fā)的編程語言,越來越受到開發(fā)者的關(guān)注和喜愛。而 Tokio 是 Rust 語言中一個(gè)非常流行的異步運(yùn)行時(shí),它提供了一系列的異步 I/O 操作,其中包括 AsyncRead 和 AsyncWrite 模塊。這兩個(gè)模塊是非常重要的,它們可以讓我們在異步編程中更加方便地讀寫數(shù)據(jù)。本教程將圍繞這兩個(gè)模塊,提供基礎(chǔ)和進(jìn)階用法的示例,幫助讀者更好地理解和使用它們。

基礎(chǔ)用法

從文件中讀取數(shù)據(jù)

use tokio::fs::File;
use tokio::io::{self, AsyncReadExt};

#[tokio::main]
async fn main() - > io::Result< () > {
    let mut file = File::open("test.txt").await?;
    let mut buffer = [0; 10];
    let n = file.read(&mut buffer).await?;
    println!("The bytes read: {:?}", &buffer[..n]);
    Ok(())
}

這個(gè)示例演示了如何使用 AsyncRead 模塊從文件中讀取數(shù)據(jù)。首先,我們使用File::open函數(shù)打開文件,然后使用read方法從文件中讀取數(shù)據(jù)。在這個(gè)示例中,我們讀取了 10 個(gè)字節(jié)的數(shù)據(jù),并將其存儲(chǔ)在一個(gè)長度為 10 的緩沖區(qū)中。最后,我們打印出讀取的字節(jié)。

從 TCP 連接中讀取數(shù)據(jù)

use tokio::net::TcpStream;
use tokio::io::{self, AsyncReadExt};

#[tokio::main]
async fn main() - > io::Result< () > {
    let mut stream = TcpStream::connect("127.0.0.1:8080").await?;
    let mut buffer = [0; 10];
    let n = stream.read(&mut buffer).await?;
    println!("The bytes read: {:?}", &buffer[..n]);
    Ok(())
}

這個(gè)示例演示了如何使用 AsyncRead 模塊從 TCP 連接中讀取數(shù)據(jù)。首先,我們使用TcpStream::connect函數(shù)連接到一個(gè) TCP 服務(wù)器,然后使用read方法從連接中讀取數(shù)據(jù)。在這個(gè)示例中,我們讀取了 10 個(gè)字節(jié)的數(shù)據(jù),并將其存儲(chǔ)在一個(gè)長度為 10 的緩沖區(qū)中。最后,我們打印出讀取的字節(jié)。

向文件中寫入數(shù)據(jù)

use tokio::fs::File;
use tokio::io::{self, AsyncWriteExt};

#[tokio::main]
async fn main() - > io::Result< () > {
    let mut file = File::create("test.txt").await?;
    let buffer = b"Hello, world!";
    file.write_all(buffer).await?;
    Ok(())
}

這個(gè)示例演示了如何使用 AsyncWrite 模塊向文件中寫入數(shù)據(jù)。首先,我們使用File::create函數(shù)創(chuàng)建一個(gè)新的文件,然后使用write_all方法將數(shù)據(jù)寫入文件中。在這個(gè)示例中,我們向文件中寫入了一個(gè)字符串"Hello, world!"。

向 TCP 連接中寫入數(shù)據(jù)

use tokio::net::TcpStream;
use tokio::io::{self, AsyncWriteExt};

#[tokio::main]
async fn main() - > io::Result< () > {
    let mut stream = TcpStream::connect("127.0.0.1:8080").await?;
    let buffer = b"Hello, world!";
    stream.write_all(buffer).await?;
    Ok(())
}

這個(gè)示例演示了如何使用 AsyncWrite 模塊向 TCP 連接中寫入數(shù)據(jù)。首先,我們使用TcpStream::connect函數(shù)連接到一個(gè) TCP 服務(wù)器,然后使用write_all方法將數(shù)據(jù)寫入連接中。在這個(gè)示例中,我們向連接中寫入了一個(gè)字符串"Hello, world!"。

讀取文件中的全部數(shù)據(jù)

use tokio::fs::File;
use tokio::io::{self, AsyncReadExt};

#[tokio::main]
async fn main() - > io::Result< () > {
    let mut file = File::open("test.txt").await?;
    let mut buffer = Vec::new();
    file.read_to_end(&mut buffer).await?;
    println!("The bytes read: {:?}", buffer);
    Ok(())
}

這個(gè)示例演示了如何使用 AsyncRead 模塊讀取文件中的全部數(shù)據(jù)。首先,我們使用File::open函數(shù)打開文件,然后使用read_to_end方法讀取文件中的全部數(shù)據(jù)。在這個(gè)示例中,我們將讀取到的數(shù)據(jù)存儲(chǔ)在一個(gè)動(dòng)態(tài)數(shù)組中,并打印出讀取的字節(jié)。

復(fù)制文件

use tokio::fs::{self, File};
use tokio::io::{self, AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() - > io::Result< () > {
    let mut source_file = File::open("source.txt").await?;
    let mut dest_file = File::create("dest.txt").await?;
    let mut buffer = [0; 1024];
    loop {
        let n = source_file.read(&mut buffer).await?;
        if n == 0 {
            break;
        }
        dest_file.write_all(&buffer[..n]).await?;
    }
    Ok(())
}

這個(gè)示例演示了如何使用 AsyncRead 和 AsyncWrite 模塊復(fù)制文件。首先,我們使用File::open函數(shù)打開源文件,使用File::create函數(shù)創(chuàng)建目標(biāo)文件。然后,我們使用一個(gè)循環(huán),每次讀取 1024 字節(jié)的數(shù)據(jù),并將其寫入目標(biāo)文件中,直到源文件讀取完畢。在這個(gè)示例中,我們使用了readwrite_all方法。

使用 BufReader 和 BufWriter

use tokio::fs::File;
use tokio::io::{self, AsyncBufReadExt, AsyncWriteExt, BufReader, BufWriter};

#[tokio::main]
async fn main() - > io::Result< () > {
    let mut file = File::open("test.txt").await?;
    let mut reader = BufReader::new(file);
    let mut writer = BufWriter::new(io::stdout());
    let mut line = String::new();
    loop {
        let n = reader.read_line(&mut line).await?;
        if n == 0 {
            break;
        }
        writer.write_all(line.as_bytes()).await?;
        line.clear();
    }
    Ok(())
}

這個(gè)示例演示了如何使用 BufReader 和 BufWriter 來進(jìn)行異步讀寫。首先,我們使用File::open函數(shù)打開文件,然后使用BufReader::new函數(shù)將文件包裝成一個(gè)緩沖讀取器,使用BufWriter::new函數(shù)將標(biāo)準(zhǔn)輸出包裝成一個(gè)緩沖寫入器。然后,我們使用一個(gè)循環(huán),每次讀取一行數(shù)據(jù),并將其寫入標(biāo)準(zhǔn)輸出中。在這個(gè)示例中,我們使用了read_linewrite_all方法。

使用 split 和 join

use tokio::fs::File;
use tokio::io::{self, AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() - > io::Result< () > {
    let mut file = File::open("test.txt").await?;
    let mut buffer = Vec::new();
    file.read_to_end(&mut buffer).await?;
    let mut parts = buffer.split(|&b| b == b'n');
    let mut tasks = Vec::new();
    while let Some(part) = parts.next() {
        let task = tokio::spawn(async move {
            let mut file = File::create("output.txt").await?;
            file.write_all(part).await?;
            Ok(())
        });
        tasks.push(task);
    }
    for task in tasks {
        task.await?;
    }
    Ok(())
}

這個(gè)示例演示了如何使用 split 和 join 來進(jìn)行異步讀寫。首先,我們使用File::open函數(shù)打開文件,然后使用read_to_end方法讀取文件中的全部數(shù)據(jù),并將其存儲(chǔ)在一個(gè)動(dòng)態(tài)數(shù)組中。然后,我們使用split方法將數(shù)據(jù)按照換行符分割成多個(gè)部分。接著,我們使用一個(gè)循環(huán),每次將一個(gè)部分異步地寫入一個(gè)新的文件中,并使用tokio::spawn函數(shù)創(chuàng)建一個(gè)異步任務(wù)。最后,我們使用join函數(shù)等待所有的異步任務(wù)完成。在這個(gè)示例中,我們使用了write_all方法。

使用 timeout

use tokio::net::TcpStream;
use tokio::io::{self, AsyncReadExt};

#[tokio::main]
async fn main() - > io::Result< () > {
    let mut stream = TcpStream::connect("127.0.0.1:8080").await?;
    let mut buffer = [0; 10];
    let n = tokio::time::timeout(std::time::Duration::from_secs(5), stream.read(&mut buffer)).await??;
    println!("The bytes read: {:?}", &buffer[..n]);
    Ok(())
}

這個(gè)示例演示了如何使用 timeout 來設(shè)置異步讀取的超時(shí)時(shí)間。首先,我們使用TcpStream::connect函數(shù)連接到一個(gè) TCP 服務(wù)器,然后使用read方法從連接中讀取數(shù)據(jù)。在這個(gè)示例中,我們使用了timeout函數(shù)來設(shè)置讀取的超時(shí)時(shí)間為 5 秒。如果在 5 秒內(nèi)沒有讀取到數(shù)據(jù),將返回一個(gè)錯(cuò)誤。在這個(gè)示例中,我們使用了time::timeout函數(shù)。

總結(jié)

本教程圍繞 Tokio 模塊的 AsyncRead 和 AsyncWrite 模塊,提供了基礎(chǔ)和進(jìn)階用法的示例。通過學(xué)習(xí)這些示例,讀者可以更好地理解和使用這兩個(gè)模塊,從而更加方便地進(jìn)行異步讀寫操作。當(dāng)然,這些示例只是冰山一角,讀者可以通過進(jìn)一步的學(xué)習(xí)和實(shí)踐,掌握更多的異步編程技巧。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 模塊
    +關(guān)注

    關(guān)注

    7

    文章

    2655

    瀏覽量

    47292
  • 編程語言
    +關(guān)注

    關(guān)注

    10

    文章

    1929

    瀏覽量

    34539
  • Rust
    +關(guān)注

    關(guān)注

    1

    文章

    228

    瀏覽量

    6542
收藏 人收藏

    評論

    相關(guān)推薦

    SQLx的基礎(chǔ)用法進(jìn)階用法

    SQLx是一個(gè)Rust語言的異步SQL數(shù)據(jù)庫訪問庫,支持多種數(shù)據(jù)庫,包括PostgreSQL、MySQL、SQLite等。本教程將以SQLite為例,介紹SQLx的基礎(chǔ)用法進(jìn)階用法。 基礎(chǔ)
    的頭像 發(fā)表于 09-19 14:29 ?2212次閱讀

    Stream模塊的基礎(chǔ)用法進(jìn)階用法

    有用。在本教程中,我們將介紹 Stream 模塊的基礎(chǔ)用法進(jìn)階用法,并提供示例。 基礎(chǔ)用法
    的頭像 發(fā)表于 09-19 15:33 ?1133次閱讀

    基于Rust語言Hash特征的基礎(chǔ)用法進(jìn)階用法

    ,包括Hash trait、HashMap、HashSet等,本教程將詳細(xì)介紹Rust語言Hash特征的基礎(chǔ)用法進(jìn)階用法。 基礎(chǔ)用法 使用Hash trait 在Rust語言中,Ha
    的頭像 發(fā)表于 09-19 16:02 ?1349次閱讀

    erode函數(shù)用法示例

    《OpenCV3編程入門》書本配套源代碼erode函數(shù)用法示例
    發(fā)表于 06-06 15:09 ?1次下載

    bilateralFilter函數(shù)用法示例

    《OpenCV3編程入門》書本配套源代碼bilateralFilter函數(shù)用法示例
    發(fā)表于 06-06 15:20 ?6次下載

    HoughLines函數(shù)用法示例

    《OpenCV3編程入門》書本配套源代碼:HoughLines函數(shù)用法示例
    發(fā)表于 06-06 15:20 ?3次下載

    MedianBlur函數(shù)用法示例

    《OpenCV3編程入門》書本配套源代碼:MedianBlur函數(shù)用法示例
    發(fā)表于 06-06 15:20 ?14次下載

    GaussianBlur函數(shù)用法示例

    《OpenCV3編程入門》書本配套源代碼:GaussianBlur函數(shù)用法示例
    發(fā)表于 06-06 15:20 ?5次下載

    remap函數(shù)用法示例

    《OpenCV3編程入門》書本配套源代碼:remap函數(shù)用法示例
    發(fā)表于 06-06 15:20 ?2次下載

    sobel函數(shù)用法示例

    《OpenCV3編程入門》書本配套源代碼:sobel函數(shù)用法示例
    發(fā)表于 06-06 15:20 ?2次下載

    pyrUp函數(shù)用法示例

    《OpenCV3編程入門》書本配套源代碼:pyrUp函數(shù)用法示例
    發(fā)表于 06-06 15:20 ?1次下載

    pyrDown函數(shù)用法示例

    《OpenCV3編程入門》書本配套源代碼:pyrDown函數(shù)用法示例
    發(fā)表于 06-06 15:20 ?16次下載

    Scharr函數(shù)用法示例

    《OpenCV3編程入門》書本配套源代碼:Scharr函數(shù)用法示例
    發(fā)表于 06-06 15:20 ?14次下載

    基于select!宏的進(jìn)階用法

    宏,它可以讓我們同時(shí)監(jiān)聽多個(gè)異步事件,一旦其中一個(gè)事件觸發(fā),就可以立即執(zhí)行相應(yīng)的代碼。在本教程中,我們將詳細(xì)介紹 select!宏的進(jìn)階用法,并提供多個(gè)示例來幫助您更好地理解和掌握這個(gè)宏的使用方法。
    的頭像 發(fā)表于 09-19 15:35 ?582次閱讀

    元組的基礎(chǔ)用法進(jìn)階用法

    元組是 Rust 語言中一種非常有用的數(shù)據(jù)結(jié)構(gòu),它可以將多個(gè)不同類型的值組合在一起。本教程將介紹元組的基礎(chǔ)用法進(jìn)階用法,并結(jié)合示例代碼進(jìn)行講解。 元組是一種有序的數(shù)據(jù)集合,其中每個(gè)元
    的頭像 發(fā)表于 09-30 16:49 ?829次閱讀