-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fs::read_dir() and ReadDir need clear warnings about not relying on iteration order #63183
Comments
The good news is that this would be a good issue for a beginner since it should just be touching docs. An example for getting entries sorted by path would be nice too. I'll gladly mentor on this if no one else is available. |
@GuillaumeGomez I can mentor on this if you'd like to mark it |
Oh nice! Adding right away. |
@rustbot claim I'd like to try dealing with this, it will be my first issue :) |
master...ali-raheem:rust-lang#63183 Is this the kind of change you were hoping for? The changes are to ReadDir and read_dir in src/libstd/fs.rs |
@ali-raheem I'd like the message to have its own header if possible, like:
I'd also like to maybe see an example of collecting the |
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
fn main() {
let path = Path::new(".");
sorted_read_dir(&path);
}
fn sorted_read_dir(path: &Path) -> io::Result<()> {
let dir = fs::read_dir(path)?;
let mut entries: Vec<PathBuf> = dir
.filter(Result::is_ok)
.map(|e| e.unwrap().path())
.collect();
entries.sort();
for entry in entries {
println!("{:?}", entry);
}
Ok(())
} Hows this for the example? |
@ali-raheem I don't think they want examples showing throwing away let mut entries = dir
.map(|res| res.map(|e| e.path()))
// this will return the iterator collected to a `Vec` or the first error
.collect::<Result<Vec<_>>>()?;
println!("Entries before sorting (may or may not be sorted already): {:?}", entries);
entries.sort();
println!("Entries after sorting: {:?}", entries); |
Okay, I've changed the example, there are two examples for read_dir now including this one. I've added the warning to ReadDir, and read_dir (and added a slightly more verbose note). Hows this looking? |
@ali-raheem Looks good, though you don't need a separate function from use std::{fs, io};
fn main() -> io::Result<()> {
// The order read_dir returns entries is not guaranteed. If reproducible
// ordering is required the entries should be explicitly sorted.
let mut entries = fs::read_dir(".")?
.map(|res| res.map(|e| e.path()))
.collect::<Result<Vec<_>, io::Error>>()?;
println!(
"Entries before sorting (may or may not be sorted already): {:?}",
entries
);
entries.sort();
println!("Entries after sorting: {:?}", entries);
Ok(())
} I would place this example as the second one, though. I would also put the same message under the header on Finally, it's "reproducible" and not "reproducable" but I can never remember which one it is either, the Firefox spell-checker had to tell me. |
@abonander Great! Here it is all together (and spell checked -- sorry!) Let me know if you're happy for me to put in a pull request. |
@ali-raheem looks good to me now, good work! |
I think this can get closed since it seems to have been resolved. Thanks for help @ali-raheem and @abonander for opening the issue |
@luigisHat this shouldn't be closed until #63356 is merged. |
Ah I see still getting used to how all this works. Thanks for letting me know @abonander |
Issue#63183: Add fs::read_dir() and ReadDir warning about iterator order + example As per rust-lang#63183 Add warning about iterator order to read_dir and ReadDir, add example of explicitly ordering direntrys.
Issue#63183: Add fs::read_dir() and ReadDir warning about iterator order + example As per rust-lang#63183 Add warning about iterator order to read_dir and ReadDir, add example of explicitly ordering direntrys.
Issue#63183: Add fs::read_dir() and ReadDir warning about iterator order + example As per rust-lang#63183 Add warning about iterator order to read_dir and ReadDir, add example of explicitly ordering direntrys.
@abonander this seems was merged to master, should it be closed now? |
The docs for
fs::read_dir()
andfs::ReadDir
need to clearly state that iteration order is implementation defined and may vary not just between OS's but between identical versions of a directory on different filesystems.Currently the warning on
fs::read_dir()
is uselessly vague:Meanwhile even this warning is completely missing from
ReadDir
.Finding the semantics on ordering requires going through the docs for the target platform:
opendir()
does not specify order but links toreaddir()
which states:FindFirstFileA
does not specify order but links toFindNextFile
which states:In both cases the relevant information is two links deep which isn't really acceptable for stdlib documentation.
I want to note that I just spent 20 minutes trying to figure this out from a unit test that was dependent on this ordering and was passing locally but failing on our CI server even though both machines are running Linux x64. The problem was I'm running btrfs (which apparently returns files in lexicographical order, or just happened to return them that way) while I'm not entirely sure what filesystem the CI server is using (build jobs are running inside Docker anyway). Either way it turns out they iterated identical copies of the same directory in different orders. Frustratingly, a very similar test also depending on the ordering of
read_dir()
but for a different directory was passing on both machines, which lead me to initially discount that it might have been an issue of iteration order.This issue has been assigned to @ali-raheem via this comment.
The text was updated successfully, but these errors were encountered: