Open a file and never close it

I know this is considered bad style, but I would like to better understand why. What happens if one opens a file and never closes it?

function sloppy()
     open("some_file", "w")
     nothing
end

sloppy()

Will the GC close this automatically? In what problems could I run, if I stop closing files?

1 Like

Yes, it will, once the file handle object is collected (or when the process terminates).

In what problems could I run, if I stop closing files?

There are maximum file handle limits and you can be unable to open any more files if you’ve opened too many and not closed them. It’s also possible to have written data to a file and have that not be flushed until the file handle is closed. You can call flush to do that explicitly but if you’re not bothering to close a file then presumably you’re not doing that either.

3 Likes

Oh, and on Windows if you have a file open then it can’t be deleted by anyone and probably various other annoying limitations.

4 Likes
julia> fn = tempname()
"/tmp/julia3mUCjj"

julia> touch(fn)
"/tmp/julia3mUCjj"

julia> manyio = [open(fn, "r") for _ in 1:10000]
ERROR: SystemError: opening file "/tmp/julia3mUCjj": Too many open files
Stacktrace:
 [1] #systemerror#43(::Nothing, ::Function, ::String, ::Bool) at ./error.jl:134
 [2] systemerror at ./error.jl:134 [inlined]
 [3] #open#309(::Bool, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Function, ::String) at ./iostream.jl:283
 [4] #open at ./none:0 [inlined]
 [5] open(::String, ::String) at ./iostream.jl:339
 [6] (::getfield(Main, Symbol("##3#4")))(::Int64) at ./none:0
 [7] iterate at ./generator.jl:47 [inlined]
 [8] collect_to!(::Array{IOStream,1}, ::Base.Generator{UnitRange{Int64},getfield(Main, Symbol("##3#4"))}, ::Int64, ::Int64) at ./array.jl:650
 [9] collect_to_with_first!(::Array{IOStream,1}, ::IOStream, ::Base.Generator{UnitRange{Int64},getfield(Main, Symbol("##3#4"))}, ::Int64) at ./array.jl:629
 [10] collect(::Base.Generator{UnitRange{Int64},getfield(Main, Symbol("##3#4"))}) at ./array.jl:610
 [11] top-level scope at none:0
2 Likes

I was thinking is there a quicker way to terminate a process (if so it could be Julia’s default)? It doesn’t seem we need to deallocate all memory (non-GC languages wouldn’t always; I’m thinking of benchmarks, to compete with them).

If closing files is actually triggered by the GC, or finalizers, then they would be left out. Since all the file handles of a program are known, it seems they could be flushed and closed by Julia on exit(). I believe the kernel (in all modern operating systems) will close the files; but will not, even can’t (fully) flush?

Right, known, and unrelated to Julia. And all those problem will go away when closed [by Julia].