Working with files in Python

Introduction

In this article you will learn how to organise working with files in Python 3.

Create the file files.py and copy the code from the examples into it.

You can run the file with the command python3 files.py

Create

You can create a file with the command open

Options:

r  read

rb reading in binary mode

w  write only.

wb writing in binary mode

w+ write and read

a  write to the end of the file - keeps the data that was in the file

Any option with w will overwrite the existing file - be careful!

Example:

f = open("log.txt","w+")

Open the file

To open a file for reading, execute

f = open("log.txt","r")

If the file log.txt does not exist, it will not be created

raceback (most recent call last): File "files.py", line 1, in <module> f = open('log.txt', 'r') FileNotFoundError: [Errno 2] No such file or directory: 'log.txt'

Close the file

To close the file, execute

f.close()

File name

An example program that prints the name of the file and the mode in which it is open

f = open('text.txt', 'r') print(f.name) print(f.mode) f.close()

If the file log.txt exists, then in the terminal you will see

text.txt
r

Context manager

It is preferable to use a context manager for working with files

As soon as you leave the block in which the file is open, it is closed automatically

with open('text.txt', 'r') as f: pass print(f.closed)

True

Read the contents of the file

with open('sites.txt', 'r') as f: f_contents = f.read() print(f_contents)

www.eth1.ru www.heihei.ru www.topbicycle.ru

All lines with a newline character - readlines

with open('sites.txt', 'r') as f: f_contents = f.readlines() print(f_contents)

['www.eth1.ru\n', 'www.heihei.ru\n', 'www.topbicycle.ru\n']

Lines one by one readline

with open('sites.txt', 'r') as f: f_contents = f.readline() print(f_contents) f_contents = f.readline() print(f_contents)

www.eth1.ru www.heihei.ru

Lines one by one without extra newlines end=''

with open('sites.txt', 'r') as f: f_contents = f.readline() print(f_contents, end = '') f_contents = f.readline() print(f_contents, end = '')

www.eth1.ru www.heihei.ru

A loop for printing line by line

with open('sites.txt', 'r') as f: for line in f: print(line, end = '')

www.eth1.ru www.heihei.ru www.topbicycle.ru

Read a certain number of characters

with open('sites.txt', 'r') as f: f_contents = f.read(20) print(f_contents)

www.eth1.ru www.heihe

If you run this command consecutively, the following characters are read

with open('sites.txt', 'r') as f: f_contents = f.read(20) print(f_contents, end = '') f_contents = f.read(20) print(f_contents, end = '')

www.eth1.ru www.heihei.ru www.topbicycle.

A loop for an arbitrary number of characters with .read

with open('sites.txt', 'r') as f: size_to_read = 10 f_contents = f.read(size_to_read) while len(f_contents) > 0: print(f_contents, end = '') f_contents = f.read(size_to_read)

www.eth1.ru www.heihei.ru www.topbicycle.ru

The expression f_contents = f.read(size_to_read) is needed so that when the file ends and f.read(size_to_read) becomes zero, len(f_contents) also becomes zero and the loop finishes

Go to an arbitrary place seek

For example, return to the beginning of the file

f.seek(0)

Copying files

Text files

They can be copied line by line

with open('sites.txt', 'r') as rf: with open('sites_copy.txt', 'w') as wf: for line in rf: wf.write(line)

cat sites_copy.txt

www.eth1.ru www.heihei.ru www.topbicycle.ru

Images

They can also be copied line by line, but they must be opened and written in binary mode. That is, you need to add the option b

Download an image of a bicycle from the site TopBicycle.ru or take any other picture

wget https://topbicycle.ru/b/img/stels_pilot_950_MD_26.jpg
ls

stels_pilot_950_MD_26.jpg

with open('stels_pilot_950_MD_26.jpg', 'rb') as rf: with open('stels_pilot_950_MD_26_copy.jpg', 'wb') as wf: for line in rf: wf.write(line)

python3 files.py
ls

stels_pilot_950_MD_26.jpg stels_pilot_950_MD_26_copy.jpg

Copying not line by line but in chunks of a fixed size is considered a more correct approach

with open('stels_pilot_950_MD_26.jpg', 'rb') as rf: with open('stels_pilot_950_MD_26_copy.jpg', 'wb') as wf: chunk_size = 4096 rf_chunk = rf.read(chunk_size) while len(rf_chunk) > 0: wf.write(rf_chunk) rf_chunk = rf.read(chunk_size)

Write to a file

To clear the file of its old contents and write a new one into it, the option is used: w (write)

with open('log.txt', 'w') as f: f.write("some text")

Append to a file

If you need to add new data to the previous contents without deleting them, the option is used: a (append)

with open('log.txt', 'a') as f: f.write("some text")

Write json to a file

import json need to get json from somewhere r = urllib.request.urlopen('http://eth1.ru/api/v1/getjson') rr = r.read() rj = json.loads(rr) with open('file.txt', 'w') as f: json.dump(rj, f)

Delete the first few lines of a file

with open('log.txt', 'a') as fin: data = fin.readlines()[1:] with open('new.txt', 'w') as fout: fout.writelines(data)

Writing the program output to a file

If you run the script from the terminal, use redirection

python script.py > script.log

In the script itself you can temporarily replace the standard output.

Suppose I make a request to an API

(More about REST API)

import sys … # Keep a reference to the original stdout original_stdout = sys.stdout with open("log.txt", "a") as f: sys.stdout = f print(resp.data) sys.stdout = original_stdout

The same applies if what arrives is json and you want to write it out nicely

import sys import json … with open("log.txt", "a") as f: sys.stdout = f print(json.dumps(resp.data, indent=4)) sys.stdout = original_stdout

Article author: Andrei Olegovich