Julia: create a new folder and file in location relative to script location

旧巷老猫 提交于 2020-03-25 03:56:38

问题


Would you happen to know how to get the path of a julia script, in a julia script?

In essence, I built a julia script named someCode.jl and it is located in a folder named repository.

When I run someCode.jl, I would like to create an output folder named output in the folder repository and put a file a.txt in folder output.

With an absolute path it works fine, but I want it to be runnable for people who put it in a different path, but I have not been able to find the right syntax yet.

Attempts

The pwd() command returns the directory in which julia is installed, which in this case is: "E:\\Users\\a\\AppData\\Local\\Julia-1.1.0" Hence I should either make sure the current path gets updated to the folder in which the script is located when I run it, or get the location of the script itself, in the script code. Neither approaches have yet been successful in julia REPL.

MWE:

This is the example file someCode.jl, I run it by opening the Julia REPL and entering: include("E:/someCode.jl")

open("c:/repository/output/a.txt", "w") do f
    n1 = "Content of  first line"
    write(f, "$n1")
end

If the repository or output folder do not exist yet, it throws error:

ERROR: LoadError: SystemError: opening file "c:/repository/output/a.txt": No such file or directory
Stacktrace:
 [1] #systemerror#43(::Nothing, ::Function, ::String, ::Bool) at .\error.jl:134
 [2] systemerror at .\error.jl:134 [inlined]
 [3] #open#309(::Nothing, ::Nothing, ::Nothing, ::Bool, ::Nothing, ::Function, ::String) at .\iostream.jl:283
 [4] #open at .\none:0 [inlined]
 [5] open(::String, ::String) at .\iostream.jl:339
 [6] #open#310(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::getfield(Main, Symbol("##7#8")), ::String, ::Vararg{String,N} where N) at .\iostream.jl:367
 [7] open(::Function, ::String, ::String) at .\iostream.jl:367
 [8] top-level scope at none:0
 [9] include at .\boot.jl:326 [inlined]
 [10] include_relative(::Module, ::String) at .\loading.jl:1038
 [11] include(::Module, ::String) at .\sysimg.jl:29
 [12] include(::String) at .\client.jl:403
 [13] top-level scope at none:0
in expression starting at E:\someCode.jl:1

So I ensured the folders c:/repository/output exist, put a second script in called 'someLocalCode.jland ran it withinclude("C:/repository/someLocalCode.jl")`:

open("c:/repository/output/a.txt", "w") do f
    n1 = "Content of  first line"
    write(f, "$n1")
end

open("output/b.txt", "w") do f
    n1 = "Content of  first line"
    write(f, "$n1")
end

open("/output/b.txt", "w") do f
    n1 = "Content of  first line"
    write(f, "$n1")
end

#include("C:/repository/test.jl")

Both output/b.txt and /output/b.txt yield (in essence) the same essence when tested individually:

ERROR: LoadError: SystemError: opening file "/output/b.txt": No such file or directory
Stacktrace:
 [1] #systemerror#43(::Nothing, ::Function, ::String, ::Bool) at .\error.jl:134
 [2] systemerror at .\error.jl:134 [inlined]
 [3] #open#309(::Nothing, ::Nothing, ::Nothing, ::Bool, ::Nothing, ::Function, ::String) at .\iostream.jl:283
 [4] #open at .\none:0 [inlined]
 [5] open(::String, ::String) at .\iostream.jl:339
 [6] #open#310(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::getfield(Main, Symbol("##15#16")), ::String, ::Vararg{String,N} where N) at .\iostream.jl:367
 [7] open(::Function, ::String, ::String) at .\iostream.jl:367
 [8] top-level scope at none:0
 [9] include at .\boot.jl:326 [inlined]
 [10] include_relative(::Module, ::String) at .\loading.jl:1038
 [11] include(::Module, ::String) at .\sysimg.jl:29
 [12] include(::String) at .\client.jl:403
 [13] top-level scope at none:0
in expression starting at C:\repository\someLocalCode.jl:6

Whereas the absolute path does function.


回答1:


Here are the options:

  • @__DIR__ macro expanding to a string with the absolute path to the directory of the file containing the macrocall
  • @__FILE__ macro expanding to a string with the path to the file containing the macrocall
  • PROGRAM_FILE constant containing the script name passed to Julia from the command line



回答2:


Thank you very much @Bogumil, implemented in the sample script the answer given can become:

# Run this script with the following command:
#include("C:/repository/someCode.jl")

# Print output file to absolute location:
open("c:/repository/output/a.txt", "w") do f
    n1 = "Content of  first line"
    write(f, "$n1")
end

# See what the commands do:
println(@__DIR__)
println(@__FILE__)
println("PROGRAM_FILE=", PROGRAM_FILE)

# Concatenate/merge the local directory with the relative output file location
directoryPath = string(@__DIR__, "/output/b.txt")
println("directoryPath concatenation=", directoryPath)

# Write the output file to a relative file location
open(directoryPath, "w") do f
    n1 = "Content of  first line"
    write(f, "$n1")
end


来源:https://stackoverflow.com/questions/55223089/julia-create-a-new-folder-and-file-in-location-relative-to-script-location

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!