Directory file tree & `walkdir()`

I’m trying to make some Julia code for (i) generating a directory/file tree at a given directory, and (ii) write the result to a CSV file.

The use case is that I have ripped my movie disks to my hard disk (no pirate copying!; I’ve purchased every disk) so that I can stream my movies from a hard disk. I need an overview of my movies so that I don’t buy movies I already own…

I’ve made some code (I will turn it into a function when I’m happy with it), so that I can run it regularly to update/generate a recent list. I’m sure the code can be made more elegant… so I’m open to suggestions (and to learn):

julia> using DelimitedFiles
julia> cd("e:/video")

My code is as follows:

file_tree = []
header = "File Tree"
file_extension = false
for (root, dirs, files) in walkdir(".")
    root_vec = split(root,"\\")
    root_name = "Folder: "*root_vec[end]
    root_length = length(root_vec)
    dir_string = fill("",root_length)
    dir_string[end] = root_name
    push!(file_tree,dir_string)
    #
    for file in files
        if file_extension
            file_name = file
        else
            file_name = splitext(file)[1]
        end
        file_string = fill("",root_length+1)
        file_string[end] = file_name
        push!(file_tree,file_string)   
    end
end
if header == ""
    popfirst!(file_tree)
else
    file_tree[1] = [header]
end
for i in 2:length(file_tree)
    popfirst!(file_tree[i])
end

I then save the resulting file tree to file:

julia> open("files.txt","w")
julia> writedlm("files.txt",file_tree,"\t");

OK… this works, and produces the following tree view (in an ASCII editor; setting file_extension = true):

Questions:

  1. Is there a more elegant/compact way to do this?
  2. Can I read the file size from walkdir() – so that I can decide whether it is a DVD or BD movie?
  3. Is there a way to close the file I open using DelimitedFiles (on Windows 10) – without restarting the computer?

You can use filesize(stat(file_name)) to get the number of bytes in the file named file_name. And you can call close() on the output of open() to close a file.

Even better, there is no need to call close() manually if you use the do-block version of open, like this:

julia> data = rand(2, 3)
2×3 Array{Float64,2}:
 0.548722  0.761118    0.876877
 0.78785   0.00870406  0.561466

julia> using DelimitedFiles

julia> open("out.csv", "w") do f
         writedlm(f, data)
       end

Using open() in this way will ensure that the file is closed automatically.

1 Like

What is the f in the do f ... end? Is it a typo — shouldn’t be there?

And — is the alternative:

julia> file = open("out.csv","w")
...
julia> close(file)?

It’s not a typo-- the f is a variable which gets bound to the open file. Check out https://docs.julialang.org/en/v1/manual/functions/index.html#Do-Block-Syntax-for-Function-Arguments-1 for a description of what’s going on.

And yes, that’s roughly the alternative, except: in your case, what happens if an error is thrown before the close(file) line? You want the file to be closed no matter what, so you might instead write something like:

file = open(...)
try 
  ...
finally
  close(file)
end

the open(...) do f method of open() takes care of all that for you.

1 Like

Thanks!