在 Julia 1.0+ 中:如何使用 redirect_stdout 获取字符串 [英] In Julia 1.0+: How do I get strings using redirect_stdout

查看:15
本文介绍了在 Julia 1.0+ 中:如何使用 redirect_stdout 获取字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

The documentation for redirect_stdouton version 1.1.0, that I am currently using, does not seem to give an example of how to use that function. Maybe I missed it?

I want to capture the output of println and get it back as a string.

Here is an example:

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

Any suggestions?

Edit

Based on the accepted answer below, here is a complete solution to my question:

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.

Edit 2: A More Complete Example

Here is an example of testing a variety of print and println function outputs using redirection of stdout. Thanks to @Bogumił Kamiński for his answer and edit that made this more clear to me:

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.
Line 2.
Line 3.
END")
    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.
Line 2.
Line 3.
END
" * 
    "This is new line 1.
This is new line 2. Next a Char = 
A"
end

# Suppress unnecessary output when this file.
return nothing

Here is the output:

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

解决方案

Just run readline on rd (or any other reading operation).

You have just to be careful that read operations on rd are blocking, i.e. the terminal will seem to hang when the operation cannot be completed. One solution is to use @async for this. For instance:

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"

Of course if you know exactly that the data you want to read in is there just run readline or some other function and all will work without @async.

EDIT

Given the comments from SalchiPapa I think it is also add this pattern of possible usage as it is simplest to think of 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)

这篇关于在 Julia 1.0+ 中:如何使用 redirect_stdout 获取字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆