Program is doing task on one disk partition instead on all available partitions

I have part of program that walks trough partition and does something with files (irrelevant for my problem). Until now that path was hardcoded, now I wanted to add feature and increase functionality so it lists all partitions on Windows PC and does something.

The problem is that Vector contains all partitions: C:, E:\ and F:\ but it only does things in C:\ partition and skipping for some reason other two partitions. I don't know reason why it is happening. I put task to do in FOR loop so it should do on all three partitions tasks.

I already checked to be sure that Vector contains all partitions, not just C:\ and it does contain them.

for partition in partitions {
     println!("{:?}", partition);

It gave me:

"C:\"
"E:\"
"F:\"

let mut partitions: Vec<String> = Vec::new();

let disks = Disks::new_with_refreshed_list();
for disk in disks.list() {
    partitions.push(disk.mount_point().to_str().unwrap().to_string());
}

for partition in partitions {
    let entries = WalkDir::new(partition)
          .into_iter()
          .filter_entry(|e| !should_skip(e))
          .collect::<Result<Vec<_>, _>>()
          .unwrap();
  
  
  entries.into_par_iter().filter(|e| e.file_type().is_file()).for_each(|entry| {
  //DOING SOMETHING IRRELEVANT ON FILES IN PARTITION
}

How are you determining that it does nothing in the other partitions?

One thing to check is what should_skip is doing.

How are you determining that it does nothing in the other partitions?

Because files in those partitions are unchanged.

One thing to check is what should_skip is doing.

should_skip is function that checks constant with hardcoded file names that program should avoid and compare it with current path. If files have same name, skip it, if not, do something with that file.

I think I found whats the problem 99.9%

I used println! with debug feature and I saw that program is trying to read and write to C:\ and it got:

thread '<unnamed>' panicked at src\bin\program.rs:63:42: Error while writing out data to file: Os { code: 32, kind: Uncategorized, message: "The process cannot access the file because it is being used by another process." }

Then I put C:\ in constant with hardcoded file names that program should avoid doing with and it worked! KINDA

It skips whole C:\ partition now but it sees E and F partitions and is doing tasks with files.

Now, since Im 99.9% sure its because its trying to read C:\ path and to write to it, I want to write line of code to see if program is trying to take C:\ - skip that "file". But if it takes anything other than that, C:\file.txt for example, then its fine. Like I said, I wrote already C:\ to constant with hardcoded files names that could be skipped, but it avoids all subpaths in C:\, instead I want it to only avoid C:\.

That's what filter_entry is documented to do.

If the predicate is false, the entry is ignored and if it is a directory, it is not descended into.

I'm not sure why your filter(|e| e.file_type().is_file()) check is not filtering out C:\. I suggest handling errors (rather than using unwrap) and printing out some debugging info when you get an error.

I'm not sure why your filter(|e| e.file_type().is_file()) check is not filtering out C:\ . I suggest handling errors (rather than using unwrap ) and printing out some debugging info when you get an error.

Me too. I thought its because filter is only done in rayon crate part of code, where tasks are done with files. So I added .filter_entry(|e| !should_skip(e) && e.file_type().is_file()) in WalkDir part and program finishes successfully but it doesnt do anything. Its just "exits successfully". It did nothing.

That's because filter_entry, when it rejects a directory, ignores everything in that directory including subfolders. That's in the doc I was referring to.

Instead use the filter method (entries.into_par_iter().filter), not filter_entry, to filter out directories. And print debugging info when there is an error, instead of using unwrap.

Now it works, but again partially. It skips C:\ but cant continue and doesnt do job on other partitons because program panicks, because now Im getting:

Error while reading file: Os { code: 32, kind: Uncategorized, message: "The process cannot access the file because it is being used by another process." } "C:\\DumpStack.log.tmp" "C:\\Users\\Default\\NTUSER.DAT.LOG1" "C:\\Users\\Default\\NTUSER.DAT{53b39e88-18c4-11ea-a811-000d3aa4692b}.TMContainer00000000000000000002.regtrans-ms" "C:\\pagefile.sys" "C:\\swapfile.sys" "C:\\Users\\Default\\NTUSER.DAT"

I see that here could be a lot of files that can make program panick.

What could I do so if program encounter on files that are already used or for which I dont have permissions, to skip that. Because I dont want all mentioned files to hardcode in constant for program to skip it. Because there could be dozens of users who will have save problem while running my program, and I cant hardcode their files. You know what I mean..

You can match on the result when opening the file (if that's where you're getting an error), for Ok process the file, and for Err don't process it and (if you'd like) log a message.

2 Likes

Awesome. That worked. I matched on reading file, if its Ok(), do irrelevant task on file. If not. Print out on command line Skipping file: FILE NAME. But I have option to instead printing out that, to do nothing - to just skip it.

Thanks man!

No problem, you're welcome!