问题
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 with
include("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 macrocallPROGRAM_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