在Julia中为每次运行创建新目录

5

我正在运行生成绘图和文本文件的Julia代码。在该代码所在的同一文件夹中存在一个名为“Output”的文件夹。对于第一次运行,我创建了一个名为“Run_1”的文件夹,并在其中创建了“Plots”和“Data”子文件夹:

fig_path = @__DIR__
mkdir(fig_path*"/Output/Run_1/")
mkdir(fig_path*"/Output/Run_1/Plots/")
mkdir(fig_path*"/Output/Run_1/Data/")

绘制完成后,我将图像保存到“Plots”中:

fig_name = "test_figure"
savefig(fig_path*"/Output/Run_1/Plots/"*fig_name*".pdf")

输出文件(包含在“output_matrix”中)被保存到“Data”中:

outfile_1 = fig_path*"/Output/Run_1/Data/test_data.txt"
open(outfile_1, "w") do f1    
    writedlm(f1,output_matrix)    
end

但是,我希望运行这段代码多次。每次运行时,应该在“输出”文件夹中创建一个新的“Run”文件夹,即第一次运行它是“Run_1”,第二次运行它是“Run_2”,以此类推。之前运行的所有文件夹都不会被删除。在每个运行文件夹中,都有一个“Plots”和一个“Data”文件夹,我在每次运行时将绘图和数据保存到它们各自的文件夹中。如何让Julia以这种方式更新文件名?


顺便提一下,您可以使用 joinpath 以更可移植的方式构建路径。 - François Févotte
此外,不要犹豫去看一下DrWatson:它是一个专门设计用于帮助管理科学项目各个方面的Julia软件包。其中包括:命名模拟以便从模拟参数中一致地派生路径(以确定性、可重复的方式)。 - François Févotte
2个回答

6

ispath函数可以检查文件系统中是否存在文件或目录。

如果您想保持命名约定,如Run_1...Run_N,可以使用类似以下内容的方法:

function mk_output_dir()
    i = 1
    while true
        dir_name = joinpath(@__DIR__, "Output", "run_$i")
        if !ispath(dir_name)
            mkpath(dir_name)
            return dir_name
        end
        i += 1
    end
end

这将产生:
# First run
julia> top_dir = mk_output_dir()
"/tmp/Output/run_1"

julia> mkdir(joinpath(top_dir, "Plots"))
"/tmp/Output/run_1/Plots"

julia> mkdir(joinpath(top_dir, "Data"))
"/tmp/Output/run_1/Data"

# Second run
julia> top_dir = mk_output_dir()
"/tmp/Output/run_2"

julia> mkdir(joinpath(top_dir, "Plots"))
"/tmp/Output/run_2/Plots"

julia> mkdir(joinpath(top_dir, "Data"))
"/tmp/Output/run_2/Data"

请注意,如果同时启动两个程序实例,则可能会发生竞态条件。



或者,我个人倾向于在创建此类目录结构时使用时间戳命名约定。以下是一个最小示例:

using Dates
function mk_output_dir()
    timestamp = Dates.format(now(), "YYYYmmdd-HHMMSS")
    dir_name = joinpath(@__DIR__, "Output", "run_$timestamp")
    @assert !ispath(dir_name) "Somebody else already created the directory"
    mkpath(dir_name)
    return dir_name
end

这将产生类似于这样的结果:

julia> top_dir = mk_output_dir()
"/tmp/Output/run_20201229-210835"

julia> mkdir(joinpath(top_dir, "Plots"))
"/tmp/Output/run_20201229-210835/Plots"

julia> mkdir(joinpath(top_dir, "Data"))
"/tmp/Output/run_20201229-210835/Data"

5
也许是这样的:

可能是这样的:

function mkresultdir(fig_path)
    for i=1:1000
        rundir = joinpath(fig_path, "run_$i")
        if !isdir(rundir)
            mkdir(rundir)
            return rundir
        end
     end
     error("too many results on disk, time for a cleanup!")
 end

res_dir_1 = mkresultdir("/home/my_user/results")
res_dir_2 = mkresultdir("/home/my_user/results")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接