From 77248d4bbd1e801c0126baffc43fa9d98c82e745 Mon Sep 17 00:00:00 2001 From: crstnbr Date: Mon, 20 Nov 2017 22:48:31 +0100 Subject: [PATCH] adding sort=true keyword to readdir() according to #24626 --- NEWS.md | 1 + base/file.jl | 19 +++++++++++++++---- test/file.jl | 14 ++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index 1df8753ba0a7b..a47056e19127a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -30,6 +30,7 @@ New library functions * The `tempname` function now takes an optional `parent::AbstractString` argument to give it a directory in which to attempt to produce a temporary path name ([#33090]). * The `tempname` function now takes a `cleanup::Bool` keyword argument defaulting to `true`, which causes the process to try to ensure that any file or directory at the path returned by `tempname` is deleted upon process exit ([#33090]). * The `readdir` function now takes a `join::Bool` keyword argument defaulting to `false`, which when set causes `readdir` to join its directory argument with each listed name ([#33113]). +* `readdir` output is now guaranteed to be sorted. The `sort` keyword allows opting out of sorting to get names in OS-native order ([#33542]). * The new `only(x)` function returns the one-and-only element of a collection `x`, and throws an `ArgumentError` if `x` contains zero or multiple elements. ([#33129]) * `takewhile` and `dropwhile` have been added to the Iterators submodule ([#33437]). diff --git a/base/file.jl b/base/file.jl index 46ed60f48ac5f..684e0fac6841e 100644 --- a/base/file.jl +++ b/base/file.jl @@ -678,7 +678,10 @@ struct uv_dirent_t end """ - readdir(dir::AbstractString=pwd(); join::Bool=false) -> Vector{String} + readdir(dir::AbstractString=pwd(); + join::Bool = false, + sort::Bool = true, + ) -> Vector{String} Return the names in the directory `dir` or the current working directory if not given. When `join` is false, `readdir` returns just the names in the directory @@ -686,8 +689,12 @@ as is; when `join` is true, it returns `joinpath(dir, name)` for each `name` so that the returned strings are full paths. If you want to get absolute paths back, call `readdir` with an absolute directory path and `join` set to true. +By default, `readdir` sorts the list of names it returns. If you want to skip +sorting the names and get them in the order that the file system lists them, +you can use `readir(dir, sort=false)` to opt out of sorting. + !!! compat "Julia 1.4" - The `join` keyword argument requires at least Julia 1.4. + The `join` and `sort` keyword arguments require at least Julia 1.4. # Examples ```julia-repl @@ -744,7 +751,7 @@ julia> readdir(abspath("base"), join=true) "/home/JuliaUser/dev/julia/base/weakkeydict.jl" ``` """ -function readdir(dir::AbstractString; join::Bool=false) +function readdir(dir::AbstractString; join::Bool=false, sort::Bool=true) # Allocate space for uv_fs_t struct uv_readdir_req = zeros(UInt8, ccall(:jl_sizeof_uv_fs_t, Int32, ())) @@ -764,9 +771,13 @@ function readdir(dir::AbstractString; join::Bool=false) # Clean up the request string ccall(:uv_fs_req_cleanup, Cvoid, (Ptr{UInt8},), uv_readdir_req) + # sort entries unless opted out + sort && sort!(entries) + return entries end -readdir(; join::Bool=false) = readdir(join ? pwd() : ".", join=join) +readdir(; join::Bool=false, sort::Bool=true) = + readdir(join ? pwd() : ".", join=join, sort=sort) """ walkdir(dir; topdown=true, follow_symlinks=false, onerror=throw) diff --git a/test/file.jl b/test/file.jl index 99f5f5dd5bba3..e15807c0adccb 100644 --- a/test/file.jl +++ b/test/file.jl @@ -1277,6 +1277,20 @@ cd(dirwalk) do end rm(dirwalk, recursive=true) +################### +# readdir # +################### +@testset "readdir is sorted" begin + mktempdir() do dir + cd(dir) do + for k in 1:10 + touch(randstring()) + end + @test issorted(readdir()) + end + end +end + ############ # Clean up # ############