A bug in fs::read_dir

when I place the exe in D drive and run this code, the read_dir result is the file list in the directory which exe lies, rather than the file list in D drive. How to fix it?

let read_path = Path::new("D:");
let dir_entries = fs::read_dir(read_path).unwrap();
for entry in dir_entries {
    println!("{:?}", entry.unwrap().file_name());
}

Isn't this normal Windows behaviour?

The path D: specifies the drive, but not the folder inside that drive so it will default to the program's current working directory. Did you mean D:\ (i.e. the \ folder on the D drive)?

8 Likes

Technically "D:" will be the "drive-relative" current directory. This is pretty arcane (it dates back to early DOS) and only really a thing if you run programs via cmd.exe. So it can behave differently in different circumstances.

So yes the fix is to use "D:\\" or r#"D:\" (using a raw string).

3 Likes

This is Windows being its usual infuriating self, yes.

Here's what happens in the console, for example:

Microsoft Windows [Version 10.0.19041.1288]
(c) Microsoft Corporation. All rights reserved.

C:\Users\myaccount>cd Q:\

C:\Users\myaccount>q:

Q:\>

cd doesn't even change the current directory :roll_eyes:

2 Likes

Specifically, that's the cmd prompt shell, not "Windows" in general. The goal of cmd is backwards compatibility with DOS batch scripts. So cd will change the current directory of the specified drive, which may not be the current drive (unless you use the /d switch to change the drive as well as directory).

Explaining why this is so would involve exploring the history of DOS. Trivia: DOS 1.0 didn't even have subdirectories, just drives.

5 Likes

Got it. Thanks!
I still have a problem. I can open C: correctly using read_dir when I place the exe in D drive, why?

A path like "C:", "D:" or "Z:" is called a "drive-relative" path. It's relative to the current directory of the drive.

So if the current directory is D:\projects\rust then D: will be interpreted as D:\projects\rust. But if you use C: and there is no current directory for the "C" drive then it defaults to C:\.

You can try this in cmd.exe. If you type cd C: or cd D: it will tell you the current directory of that drive. Try switch between drives and setting different current directories.

I see. Thanks!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.