隱私權政策

搜尋此網誌

技術提供:Blogger.

關於我自己

我的相片
目前從事軟體相關行業,喜歡閱讀、健身、喝調酒。習慣把遇到的問題記下來,每天做一些整理方便自己以後查。 Python、Rust、Kotlin等程式語言皆為自學,目前比較著重在Rust語言,歡迎一起討論。

2023年12月25日 星期一

Rust Seek概述 - 移動檔案內游標位置


Trait std::io::Seek [1]

Seek是一個Trait

主要作用可以使檔案中的游標移動


讀取例子

假設我有一個文件example.txt

裡面內容是abcdefghijklmnopqrstuvwxyz



希望從第六個開始讀

也就是讀取fghijklmnopqrstuvwxyz

可以這樣做

use std::{
    fs::OpenOptions,
    io::{Read, Seek, SeekFrom},
};

fn main() {
    let mut file = OpenOptions::new()
        .read(true)
        .open("example.txt")
        .unwrap();

    file.seek(SeekFrom::Start(5)).unwrap();
    let mut buf = String::new();
    file.read_to_string(&mut buf).unwrap();
    println!("{:?}", buf);
}
"fghijklmnopqrstuvwxyz"

先使用OpenOptions[2]開啟檔案

OpenOptions為主要為設定開啟檔案的方式

因為這次需要讀取檔案

要把read設定為true

再用open輸入路徑,最後unwrap


之後就可以控制游標了

file.seek(SeekFrom::Start(5))表示游標從第六個開始

SeekFrom[3]有三種枚舉

分別是Start, End, Current

pub enum SeekFrom {
    Start(u64),
    End(i64),
    Current(i64),
}

SeekFrom::Start

從0開始設定游標位置


SeekFrom::End

從最後開始設定游標位置

use std::{
    fs::OpenOptions,
    io::{Read, Seek, SeekFrom},
};

fn main() {
    let mut file = OpenOptions::new()
        .read(true)
        .open("example.txt")
        .unwrap();
    file.seek(SeekFrom::End(-5)).unwrap();
    let mut buf = String::new();
    file.read_to_string(&mut buf).unwrap();
    println!("{:?}", buf);
}
"vwxyz"

使用-5這樣表示從最後面數來第五個開始


SeekFrom::Current

將游標從現在位置移到幾個數字後的位置

例如

use std::{
    fs::OpenOptions,
    io::{Read, Seek, SeekFrom},
};

fn main() {
    let mut file = OpenOptions::new()
        .read(true)
        .open("example.txt")
        .unwrap();

    file.seek(SeekFrom::Start(0)).unwrap();
    file.seek(SeekFrom::Current(5)).unwrap();
    let mut buf = String::new();
    file.read_to_string(&mut buf).unwrap();
    println!("{:?}", buf);
}
"fghijklmnopqrstuvwxyz"

設定初始為0,要移到第五個位置

可以使用Current(5)表示移到五個後的位置

另外Current也可以是負的

use std::{
    fs::OpenOptions,
    io::{Read, Seek, SeekFrom},
};

fn main() {
    let mut file = OpenOptions::new()
        .read(true)
        .open("example.txt")
        .unwrap();
    file.seek(SeekFrom::Start(10)).unwrap();
    file.seek(SeekFrom::Current(-5)).unwrap();
    let mut buf = String::new();
    file.read_to_string(&mut buf).unwrap();
    println!("{:?}", buf);
}
"fghijklmnopqrstuvwxyz"

負的表示現在位置往前多少


撰寫例子

use std::{
    fs::OpenOptions,
    io::{Seek, SeekFrom, Write},
};

fn main() {
    let mut file = OpenOptions::new()
        .write(true)
        .open("example.txt")
        .unwrap();
    file.seek(SeekFrom::Start(5)).unwrap();
    let buf = String::from("1234567890");
    file.write_all(buf.as_bytes()).unwrap();
}

一樣把游標先移到第五個

write_all會把原本文件的文字覆蓋

也就是文件會變成這個樣子




參考資料

[1] https://doc.rust-lang.org/std/io/trait.Seek.html

[2] https://doc.rust-lang.org/std/fs/struct.OpenOptions.html

[3] https://doc.rust-lang.org/std/io/enum.SeekFrom.html


0 comments:

張貼留言