在Julia 1.0+;中:如何使用重定向\u stdout获取字符串

在Julia 1.0+;中:如何使用重定向\u stdout获取字符串,julia,Julia,我目前使用的版本1.1.0上的for重定向\u stdout,似乎没有给出如何使用该函数的示例。也许我错过了 我想捕获println的输出并将其作为字符串返回 以下是一个例子: julia> VERSION v"1.1.0" julia> (rd, wr) = redirect_stdout(); julia> println("This is a test.") julia> # Get back the string "This is a test." jul

我目前使用的版本1.1.0上的for
重定向\u stdout
,似乎没有给出如何使用该函数的示例。也许我错过了

我想捕获
println
的输出并将其作为字符串返回

以下是一个例子:

julia> VERSION
v"1.1.0"

julia> (rd, wr) = redirect_stdout();

julia> println("This is a test.")

julia> # Get back the string "This is a test."

julia> # s = do_something_with_rd(rd)

julia> # s == "This is a test."

julia> # true
有什么建议吗

编辑

根据以下公认的答案,以下是我问题的完整解决方案:

julia> original_stdout = stdout;

julia> (rd, wr) = redirect_stdout();

julia> println("This is a test.")

julia> s = readline(rd)
"This is a test."

julia> s == "This is a test."
true

julia> redirect_stdout(original_stdout);

julia> println("Test of orig. stdout.")
Test of orig. stdout.
编辑2:更完整的示例

下面是一个使用重定向
stdout
测试各种
print
println
函数输出的示例。感谢@BogumiłKamiński的回答和编辑,让我更清楚地认识到这一点:

using Test

# Test redirect_stdout.
@testset "Example tests using redirect_stdout" begin
    original_stdout = stdout;
    (read_pipe, write_pipe) = redirect_stdout();
    print("Using print function.")
    println("Using println function.")
    println("Second use of println function.")
    println("Line 1.\nLine 2.\nLine 3.\nEND")
    println("""
    This is new line 1.
    This is new line 2. Next a Char = """)
    print('A')
    redirect_stdout(original_stdout);
    close(write_pipe)
    @test readline(read_pipe) == "Using print function.Using println function."
    @test readline(read_pipe) == "Second use of println function."
    @test read(read_pipe, String) == "Line 1.\nLine 2.\nLine 3.\nEND\n" * 
    "This is new line 1.\nThis is new line 2. Next a Char = \nA"
end

# Suppress unnecessary output when this file.
return nothing
以下是输出:

julia> include("test_redirect_stdout.jl")
Test Summary:                       | Pass  Total
Example tests using redirect_stdout |    3      3

只需在
rd
上运行
readline
(或任何其他读取操作)

您只需小心,
rd
上的读取操作被阻塞,即当操作无法完成时,终端似乎会挂起。一种解决方案是为此使用
@async
。例如:

julia> (rd, wr) = redirect_stdout();

julia> @async global x = readline(rd) # if we did not put @async here the terminal would be blocked
Task (runnable) @0x0000000004e46e10

julia> x # x is yet undefined as readline is waiting for an input
ERROR: UndefVarError: x not defined

julia> println("something") # we feed data to stdout

julia> x # and readline has finished its work and bound the value to variable x
"something"
当然,如果您确切知道要读取的数据在那里,只需运行
readline
或其他一些函数,所有这些函数都可以在没有
@async
的情况下工作

编辑

鉴于IMO的评论,我认为还可以添加这种可能的用法模式,因为这是IMO最简单的想法:

original_stdout = stdout
(rd, wr) = redirect_stdout();

println("This is a test 1.")
println("This is a test 2.")
println("This is a test 3.")

redirect_stdout(original_stdout)

# you can still write to wr
println(wr, "This is a test 4.")

# you have to close it to make the read non-blocking
close(wr)

# the pipe is redirected to original stdout and wr is closed so this is non-blocking    
s = read(rd, String)

您可以使用
sprint
AKA“字符串打印”:


同意,但
sprint
redirect\u stdout
旨在处理不同的用例。当我运行第三方代码,向
stdout
写入内容并想要捕获它时,我使用
redirect\u stdout
。在这种情况下,您不能使用
sprint
。是捕获外部解算器输出的示例。问题是如何使用
重定向\u stdout
(但对于简单的情况,您的答案确实是一个更好的解决方案)。也许它对他的抑制器也有用。@capture\u out,它在下面使用IO流重定向。很好的观点-事实上,我认为根据您的评论更新我的答案是值得的。@SalchiPapa关于'suppersor's@capture\u out宏的观点很好。我试过了,效果很好。然而,我想在Base Julia中找到一个解决方案,而公认的答案就是这样。不管怎么说,盒子里有另一个工具是很好的。@Julia Learner您也可以将粘贴
@capture\u out
几乎一字不差地复制到您的代码库中,因为它只使用
,但是您会错过更新和错误修复。
julia> sprint(println, "This is a test")
"This is a test\n"