julia> open("/tmp/tst", "w") do f write(f, ones(Int64, 2)) end
16
julia> a = Array{Int64}(uninitialized, 4)
4-element Array{Int64,1}:
140008466987408
140008481884256
140008466986384
0
julia> rr = read!("/tmp/tst", a)
ERROR: EOFError: read end of file
Stacktrace:
[1] unsafe_read at ./iostream.jl:409 [inlined]
[2] unsafe_read at ./io.jl:588 [inlined]
[3] macro expansion at ./gcutils.jl:82 [inlined]
[4] read! at ./io.jl:606 [inlined]
[5] #282 at ./io.jl:299 [inlined]
[6] #open#316(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::getfield(Base, Symbol("##282#283")){Array{Int64,1}}, ::String, ::Vararg{String,N} where N) at ./iostream.jl:369
[7] open at ./iostream.jl:367 [inlined]
[8] read!(::String, ::Array{Int64,1}) at ./io.jl:299
[9] top-level scope
julia> rr
ERROR: UndefVarError: rr not defined
julia> a # a is partially changed
4-element Array{Int64,1}:
1
1
140008466986384
0
read!(stdin, a)
julia> stat(stdin)
ERROR: MethodError: no method matching joinpath(::Base.TTY)
Assuming that there is enough data? I don’t think it is good programmer practice!
I probably found source of this problem:
function unsafe_read(s::IOStream, p::Ptr{UInt8}, nb::UInt)
if ccall(:ios_readall, Csize_t,
(Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), s, p, nb) != nb
throw(EOFError())
end
nothing
end
C code seems to be correct but encapsulation to Julia hides useful information.
help doesn’t say it but read!(io, array) returns array:
function read!(s::IO, a::Array{UInt8})
GC.@preserve a unsafe_read(s, pointer(a), sizeof(a))
return a
end
function read!(s::IO, a::Array{T}) where T
if isbits(T)
GC.@preserve a unsafe_read(s, pointer(a), sizeof(a))
else
for i in eachindex(a)
a[i] = read(s, T)
end
end
return a
end
I think it is redundant because array is known and could be better to make here backward incompatible change before 1.0
I think fx!() might generally be expected to fill/use all of the overwrite argument space, otherwise it probably wouldn’t have the Throw(EOFError()) (// possibly better off using a non-! version?). There’s also lstat() though it doesn’t work for STDIN, but you should probably just be using readline with STDIN and parsing, i don’t think you can get a pair of float64 direct from an ordinary keyboard