0

I want to read all the files in the current directory.

Here's my progress:

use std::fs;

fn main() {
    let files = fs::read_dir(".").unwrap();
    files
        .filter_map(Result::ok)
        .filter(|d| if let Some(e) = d.path().extension() { e == "txt" } else {false})
        .for_each(|f| println!("{:?}", f));
}

Here I got a little lost, how can I read all file contents? Should I add them to a growing Vec in the for_each block? if so then how?

Optimistic Peach
  • 3,862
  • 2
  • 18
  • 29
toti
  • 325
  • 4
  • 12
  • 3
    You want to read the byte contents of every file in `.` into a flat `Vec`, in arbitrary order (whatever order `read_dir` gives you)? Or do you want it to have some structure like keeping track of which contents go with which filename? – trent Jun 02 '20 at 21:43
  • See also: https://stackoverflow.com/questions/31192956/whats-the-de-facto-way-of-reading-and-writing-files-in-rust-1-x – E_net4 Jun 03 '20 at 08:50

1 Answers1

1

If you want a single vec with all files bytes in one you can use

let target_ext = OsString::from("txt");
let files = fs::read_dir(".").unwrap();
let file_bytes : Vec<u8> = files
    .filter_map(Result::ok)
    .map(|d| d.path())
    .filter(|path| path.extension() == Some(&target_ext))
    .flat_map(|path| fs::read(path).expect("Failed to read"))
    .collect();

if you want a vec that contains each file's content separately, change flat_map to a map and it will return a Vec<Vec<u8>>

let file_bytes : Vec<Vec<u8>> = files
    .filter_map(Result::ok)
    .map(|d| d.path())
    .filter(|path| path.extension() == Some(&target_ext))
    .map(|path| fs::read(path).expect("Failed to read"))
    .collect();
pigeonhands
  • 3,066
  • 15
  • 26
  • `flat_map`ping an iterator of `Vec` will copy all the file contents at least twice, and makes a lot of churn for the allocator. It might be better to use `for_each` and `read_to_end` each file into a single `Vec`. Also, a `Vec>` doesn't strike me as terribly useful when you don't know what files the `Vec`s correspond to; I would have gone for a `HashMap>` or something (but it would be better if the OP can clarify the desired result). – trent Jun 03 '20 at 15:47