Skip to content
AgileLogics
6 min read

Files and I/O

Prerequisites: Error handling

Writing and reading whole files

write("notes.txt", "first line\nsecond line\n")
println(read("notes.txt", String))
println(readlines("notes.txt"))
println(isfile("notes.txt"), " ", filesize("notes.txt"))
first line
second line

["first line", "second line"]
true 23

write(path, data) creates or overwrites a file; read(path, String) and readlines(path) read it back.

open with a do block

open("log.txt", "w") do io
    println(io, "started")
    for i in 1:3
        println(io, "step $i")
    end
end

open("log.txt", "a") do io
    println(io, "finished")
end

for (n, line) in enumerate(eachline("log.txt"))
    println(n, ": ", line)
end
1: started
2: step 1
3: step 2
4: step 3
5: finished
  • Modes: "r" read (default), "w" write, "a" append.
  • The do block closes the file automatically — even if an error happens inside it.
  • println(io, ...) and print(io, ...) write to any IO stream.
  • eachline reads one line at a time, so it works for huge files.

Parsing a simple CSV by hand

write("sales.csv", """
region,amount
north,120
south,80
north,45
east,60
""")

totals = Dict{String,Int}()
for line in Iterators.drop(eachline("sales.csv"), 1)
    region, amount = split(line, ",")
    totals[region] = get(totals, region, 0) + parse(Int, amount)
end
for region in sort(collect(keys(totals)))
    println(rpad(region, 6), totals[region])
end
east  60
north 165
south 80

Iterators.drop(itr, 1) skips the header line. For real CSV files (quoted fields, missing values, types), use CSV.jl — covered in the DataFrames lesson. The DelimitedFiles standard library (readdlm, writedlm) handles simple numeric tables.

Paths and directories

mkpath(joinpath("data", "raw"))
write(joinpath("data", "raw", "a.txt"), "hi")
println(readdir("data"))
println(basename("data/raw/a.txt"), " ", splitext("report.csv"))
println(isdir("data"), " ", ispath("missing.txt"))
rm("data", recursive = true)
println(isdir("data"))
["raw"]
a.txt ("report", ".csv")
true false
false

Always build paths with joinpath so your code works on Windows, macOS, and Linux. @__DIR__ gives the folder of the current source file — use it to find data files next to your script.

In-memory IO

io = IOBuffer()
print(io, "a=", 1)
print(io, ", b=", 2)
println(String(take!(io)))
println(sprint(print, [1, 2, 3]))
a=1, b=2
[1, 2, 3]

An IOBuffer behaves like a file in memory — useful for building large strings efficiently and for testing functions that write to an io.