$ cat input.txt
First line.
Second line.
Last line.
Read line by line
| (1) read line by line
|
f = open("input.txt", "r")
for line in f:
line = line.rstrip("\n")
print(line)
f.close()
|
let f = open("input.txt", fmRead)
for line in f.lines:
echo line # !!! no newline at the end !!!
f.close()
|
The output is the same:
First line.
Second line.
Last line.
Notice that in Nim, the variable line doesn't contain the newline character at the end.
fmRead is the file mode — Nim uses an enum for this. Modes used most often: fmRead, fmWrite and fmAppend. See the docs for all the available modes.
How to make it more robust?
Python has its with block that guarantees that the file will be properly closed, even if there was an exception. How to do that in Nim?
| (1b) with block / defer
|
with open("input.txt", "r") as f:
for line in f:
line = line.rstrip("\n")
print(line)
|
proc main() =
let f = open("input.txt", fmRead)
defer: f.close()
for line in f.lines:
echo line
when isMainModule:
main()
|
defer is not supported on the top level, that's why I put the code inside a proc. More on defer later. In short: it guarantees f.close() is called when the current scope exits, regardless of how it exits (with or without an exception).
Write to a text file
Open the file in fmWrite mode.
| (2) write
|
with open("out_py.txt", "w") as f:
print("hello", file=f)
f.write("aa")
f.write("bb\n")
f.write("END\n")
|
proc main() =
let f = open("out_nim.txt", fmWrite)
defer: f.close()
f.writeLine("hello") # adds newline
f.write("aa") # no implicit newline
f.write("bb\n")
f.write("END\n")
when isMainModule:
main()
|
The contents of the output files are identical:
Warning! If you open an existing file in write mode, then it'll be overwritten! You'll lose the original content! So be careful.
Append to a text file
Similar to writing but the file must be opened in fmAppend mode. In Python, it's mode "a". After that, when you write something in the file, it'll be written to the end of the file. If the file existed, it won't be overwritten.