如何從rayons `par_iter`中寫入文件?

“我是Rust的新手,我正在做一個項目,需要掃描大量文件夾中的文件,并將過濾后的數(shù)據(jù)保存到JSON文件中。我目前正在使用Rayon對包含文件夾的‘Vec’執(zhí)行快速foreach循環(huán)。在循環(huán)中,我讀取一個文件,過濾有用的信息,并將其保存到一個文件中。

這是最終的工作版本。然而,我懷疑這不是最好的解決方案。

fn main() {
    // ...

    // Imagine this is full of data
    let mut folder_nas: Vec<FolderNAS> = Vec::new();

    // Open a out.json file to store the results in append mode
    let mut file = OpenOptions::new()
        .write(true)
        .append(true)
        .open(FILENAME)
        .unwrap();
    file.write_all("Some data").unwrap();

    folder_nas.par_iter().for_each(|x| {
        let mut file_iterator = OpenOptions::new()
            .write(true)
            .append(true)
            .open(FILENAME)
            .unwrap();
        file_iterator
            .write_all("Some filtered data")
            .unwrap();
    });
    file.write_all("Some data").unwrap();
}

起初,來自其他語言的我嘗試過這個。

fn main() {
    // ...

    // Imagine this is full of data
    let mut folder_nas: Vec<FolderNAS> = Vec::new();

    // Open a out.json file to store the results in append mode
    let mut file = OpenOptions::new()
        .write(true)
        .append(true)
        .open(FILENAME)
        .unwrap();
    file.write_all("Some data").unwrap();

    folder_nas.par_iter().for_each(|x| {
        // Notice the name difference
        file.write_all("Some filtered data")
            .unwrap();
    });
    file.write_all("Some data").unwrap();
}

這種方法最終給了我一個錯誤,因為file變量在for_each及更高版本中使用。我的解決方案是在for_each中打開一個新的OpenOptions編寫器。但我的問題是,我如何使用file變量而不創(chuàng)建新的編寫器?

? 最佳回答:

正如Chayim Friedman在評論中所展示的那樣,你真的不需要為了寫入File而對其進行變異。這是因為&File實現(xiàn)了Write,反映了這樣一個事實,即從多個threads寫入OS-level文件句柄是完全可以的。然而,這種方法存在兩個問題:

  • 無法保證File::write_all()能夠一口氣寫出所有內(nèi)容。如果基礎(chǔ)File::write()指示只寫入了數(shù)據(jù)的一部分,它將發(fā)出一個新的write()來寫出其余的數(shù)據(jù)。這個write()可能是在另一個thread發(fā)出自己的write()之后發(fā)生的,導(dǎo)致文件中的數(shù)據(jù)交錯(損壞)。
  • 如果你決定將File打包成BufWriter,那么這個技巧就行不通了。如果你要寫出non-trivial量的數(shù)據(jù),這是一件非常合理的事情。

因此,我建議只使用Mutex,它可以解決這兩個問題(這也是像C和C++這樣的語言在后臺所做的):

let mut file = OpenOptions::new()
    .write(true)
    .append(true)
    .open("out.json")
    .unwrap();
file.write_all(b"Some data").unwrap();

// wrap file in a Mutex to use it in parallel
let file = Mutex::new(file);
folder_nas.par_iter().for_each(|_x| {
    // lock the mutex to access the file
    file.lock().unwrap().write_all(b"Some filtered data").unwrap();
});
// extract the original file and use it as before
let mut file = file.into_inner().unwrap();
file.write_all(b"Some data").unwrap();

Playground

主站蜘蛛池模板: 午夜福利无码一区二区| 国产AV午夜精品一区二区三区| 日韩精品乱码AV一区二区| 濑亚美莉在线视频一区| 人妻无码一区二区不卡无码av| 丝袜美腿高跟呻吟高潮一区| 成人免费观看一区二区| 日本一区二区免费看| 亚洲熟女一区二区三区| 国产伦精品一区二区三区免.费| 91精品乱码一区二区三区| 人妻体内射精一区二区三四| 中文字幕一区二区三区乱码| www一区二区三区| 日本精品少妇一区二区三区| 国产精品一区电影| 国产成人精品亚洲一区 | 亚洲制服中文字幕第一区| 亚洲一区日韩高清中文字幕亚洲| 精品一区二区AV天堂| 色精品一区二区三区| 精品女同一区二区| 日韩经典精品无码一区| 亚洲国产精品一区二区九九 | 亚洲国产精品综合一区在线| 亚洲成AV人片一区二区密柚| 久久国产精品视频一区| 一区二区三区国产精品 | 久久久91精品国产一区二区| 国产成人无码精品一区二区三区| 熟女精品视频一区二区三区| 亚洲av无码一区二区三区观看 | 在线观看国产一区| 国产一区二区免费视频| 乱子伦一区二区三区| 精品国产一区二区三区AV| 精品不卡一区中文字幕| 国产亚洲3p无码一区二区| 秋霞无码一区二区| 免费一区二区三区四区五区| 精品乱子伦一区二区三区|