I/O Operations in Julia
Learn console output, reading input, file reading and writing, formatted output, and I/O error handling in Julia with Docker-ready examples
Input and output are how a program talks to the outside world—the terminal, files on disk, network sockets, and pipes. In the Hello World tutorial you met println, but that was only the surface. Julia treats I/O through a uniform abstraction: everything readable or writable is a stream (an IO object), and the same functions—read, write, print, println—work on all of them thanks to multiple dispatch.
This uniformity is one of Julia’s quiet strengths. Because stdout, an open file, and an in-memory buffer are all just IO values, a function that writes to one can write to any of them without change. You will see this when we redirect output to stderr or a file simply by passing a different first argument.
In this tutorial you will learn how to write to the console with fine control, read input from the user, read and write files, produce formatted output with the Printf standard library, and handle the errors that inevitably arise when files go missing. As a language built for scientific computing, Julia leans on the do-block pattern to guarantee files are closed even when something goes wrong.
Console Output
println writes a value followed by a newline; print omits the newline. For anything more structured, the Printf standard library provides C-style format strings via the @printf and @sprintf macros. The show function prints a value’s programmatic representation (the form you would type to recreate it).
Create a file named console_output.jl:
| |
The last line demonstrates dispatch on streams: println(stderr, ...) sends text to stderr instead of stdout. The eight lines before it all print to stdout. Running this produces on standard output:
println adds a newline
print does not — see?
Language: Julia, version 1.11
Pi to 4 places: 3.1416
Padded integer: | 42|
Hex: ff, Octal: 10
Formatted string: 0003.142
[1, 2, 3]
Reading Console Input
readline() reads one line from standard input and returns it as a String (without the trailing newline). Since input always arrives as text, use parse to convert it to a number.
Create a file named greet_input.jl:
| |
Because the prompts use print (no newline) and the piped input is not echoed back, feeding Ada and 7 into the program produces:
Enter your name: Hello, Ada!
Enter a number: Its square is 49
When running interactively in a terminal, you would see your typed input appear between the prompt and the response.
Writing and Reading Files
The idiomatic way to work with a file is open(filename, mode) do file ... end. The do-block form passes the open stream to the block and automatically closes it when the block finishes—even if an error is thrown. Common modes are "w" (write, truncating), "a" (append), and "r" (read, the default).
Julia offers several ways to read back: read(path, String) slurps the whole file into a string, eachline(path) iterates lazily line by line, and readlines(path) returns a Vector of all lines.
Create a file named io_operations.jl:
| |
I/O Error Handling
File operations can fail—the file may not exist, or permissions may be wrong. Julia signals these with a SystemError, which you catch using try/catch. You can also check ahead of time with isfile, and inspect a file with filesize.
Create a file named safe_read.jl:
| |
Running this yields:
Error: could not open 'missing.txt'
missing.txt is not present
Running with Docker
You can run every example without installing Julia locally.
| |
The -v $(pwd):/app mount lets the container write notes.txt back into your current directory, so you can inspect the file after the run.
Expected Output
Running io_operations.jl produces:
File written.
Full contents:
Julia I/O Demo
Line 2 of 3
Line 3 of 3
Numbered lines:
1: Julia I/O Demo
2: Line 2 of 3
3: Line 3 of 3
Total lines now: 4
Key Concepts
- Everything is a stream —
stdout,stderr, open files, and in-memory buffers are allIOobjects, soprint,println,read, andwritework uniformly on any of them via multiple dispatch. - The
do-block closes files for you —open(name, mode) do file ... endguarantees the file is closed even if an exception is thrown, making it the safest and most idiomatic pattern. - Choose your read strategy —
read(path, String)loads everything at once,eachline(path)iterates lazily (ideal for large files), andreadlines(path)returns a vector of lines. Printffor formatted output —@printfprints with C-style format specifiers, while@sprintfreturns the formatted text as aString; both requireusing Printf.- Input is always text —
readline()returns aString; useparse(Int, ...)orparse(Float64, ...)to convert numeric input. - Handle failures with
try/catch— missing or unreadable files raise aSystemError; catch it, or guard withisfilebefore opening. - Redirect by argument, not by API — sending output to a file or to
stderris just a matter of passing a different first argument, with no separate stream API to learn.
Comments
Loading comments...
Leave a Comment