Trying to populate a structure inside a for loop but getting "MethodError: Cannot `convert` an object of type String to an object of type file_info"

just starting out and trying to get information about an directory on a linux disk that I pass as an arguement. I thought I’d try out building a structure use it to define an array. Then I would add each file’s information as it gets parsed. BUT I am getting the error below and I am not sure why?

thanks for any help AND if there is a better way to go about this happy to listen.

using Dates

struct file_info
       path::String
       human_time :: DateTime
       unix_time :: DateTime
end

for (root, dirs, files) in walkdir(ARGS[1])

    today_file_info = file_info[]
   
    for file in files
        filePath = joinpath(root, file);
        lastUpdatedTime = unix2datetime(stat(filePath).mtime);
        raw_time = stat(filePath).mtime
        println("=============")
        println(filePath,"   ", lastUpdatedTime, "   ", raw_time )   
        println("=============")
        push!(today_file_info, filePath, lastUpdatedTime, raw_time)
    end
    
end

dave@deepthought:~/tontine_2022/sandbox$ julia "1_29_22_getting_file_dates.jl" /home/dave/tontine_2022
=============
/home/dave/tontine_2022/config/1 10 22 all the csv files.ods   2022-01-10T22:16:31.361   1.641852991361334e9
=============
ERROR: LoadError: MethodError: Cannot `convert` an object of type String to an object of type file_info
Closest candidates are:
  convert(::Type{T}, ::T) where T at ~/julia-1.7.0/share/julia/base/essentials.jl:218
  file_info(::String, ::DateTime, ::DateTime) at ~/tontine_2022/sandbox/1_29_22_getting_file_dates.jl:4
  file_info(::Any, ::Any, ::Any) at ~/tontine_2022/sandbox/1_29_22_getting_file_dates.jl:4
Stacktrace:
 [1] setindex!(A::Vector{file_info}, x::String, i1::Int64)
   @ Base ./array.jl:903
 [2] _append!
   @ ./array.jl:1060 [inlined]
 [3] append!
   @ ./array.jl:1050 [inlined]
 [4] push!
   @ ./array.jl:1051 [inlined]
 [5] top-level scope
   @ ~/tontine_2022/sandbox/1_29_22_getting_file_dates.jl:23
in expression starting at /home/dave/tontine_2022/sandbox/1_29_22_getting_file_dates.jl:12
dave@deepthought:~/tontine_2022/sandbox$ 

The following

using Dates

struct file_info
       path::String
       human_time :: DateTime
       unix_time :: Float64
end

for (root, dirs, files) in walkdir(".")

    today_file_info = file_info[]

    for file in files
        filePath = joinpath(root, file);
        lastUpdatedTime = unix2datetime(stat(filePath).mtime);
        raw_time = stat(filePath).mtime
        println("=============")
        println(filePath,"   ", lastUpdatedTime, "   ", raw_time )
        println("=============")
        push!(today_file_info, file_info(filePath, lastUpdatedTime, raw_time))
    end

end

seems to work for me.

2 Likes

thanks so much for helping me out. I certainly didn’t have clue as to how the struct mapping worked. Also thank you for fixing the unix_time cockup. I missed that one as well.

Is there a more interesting way to get this information in Julia?

I just want to see the chronology of the file changes in a linux directory. I was thinking about messing around with calling bash functions but thought to learn a little about julia instead.

Maybe you want to watch for changes?

I looked into that using FileWatching and Glob. Remember I’m a noob so bear with me. My usecase is that I am using a cronjob to start a couple of python scripts that feeds data ever 5 seconds to two csv files. The file names are new everyday and constructed from a fixed name with date time info attached.
the_daily_hedgehog_data_1_29_22_8_30.csv and so on. Another cronjob moves them overnight to another directory. I prefer to use cron for these tasks as it’s pretty robust. I know I could do it programmatically.

I want to know the name of those files so I can get a Julia script to start reading them as soon as the cronjob starts it up. So the python scripts are already running.

I know I could use the splendid PyCall for this or the equally excellent ZMQ but, for now, I want to have build a csv file of the data ( simplest approach), read it into a julia script and mess around with it there.

If there is a more Julia way of getting this done please point me at it. I’ll certainly go back to FileWatching but this way seemed a lot simpler.
happy to be advised on this. I want to set off properly.

thanks again for helping me here.

1 Like