Fichiers

by Christian Nguyen, Joseph Razik, on 2019-10-18
fichiers

Ouverture d'un fichier en mode texte

In [1]:
import pocketnoobj
Initialisation de l'espace de nommage fait.
In [2]:
# reconnaitre les messages d'erreur

# le fichier n'existe pas
nom = 'nexistepas'
open(nom)
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-2-6bf58a9c2156> in <module>()
      3 # le fichier n'existe pas
      4 nom = 'nexistepas'
----> 5 open(nom)

FileNotFoundError: [Errno 2] No such file or directory: 'nexistepas'
In [3]:
# ce que confirme le shell
In [4]:
ls nexistepas
ls: impossible d'accéder à 'nexistepas': Aucun fichier ou dossier de ce type
In [5]:
# pas les droits sur le fichier
# ne pas oublier de créer le fichier sans les droits de lecture pour que cet exemple
nom = 'paspermi'
open(nom)
---------------------------------------------------------------------------
PermissionError                           Traceback (most recent call last)
<ipython-input-5-2d51850732a8> in <module>()
      2 # ne pas oublier de créer le fichier sans les droits de lecture pour que cet exemple
      3 nom = 'paspermi'
----> 4 open(nom)

PermissionError: [Errno 13] Permission denied: 'paspermi'
In [6]:
# ce que confirme le shell également avec les droits --w--w---- (pas de lecture 'r')
In [7]:
ls -nl paspermi
--w--w----. 1 1013 1014 0  8 mars  10:28 paspermi
In [8]:
# quand tout fonctionne bien, deux manières de travailler proprement avec un fichier:
# 1. ouverture et fermeture explicite
f = open('modulex.py')
close(f)
    
# 2. ouverture explicite et fermeture implicite
with open('modulex.py') as f:
    pass
In [9]:
ls -nl modulex.py
-rw-rw-r--. 1 1013 1014 991  8 mars  10:29 modulex.py

Lecture du contenu caractère par caractère

In [10]:
# un fichier n'est qu'une longue chaîne d'octets et possède un indicateur de position courante du "curseur"
# les opérations de lecture/écriture se font par rapport à la position de curseur et le font avancer du
# d'octets lus/écrits
# les fonctions seek et tell permettent respectivement de position ou connaitre la position du curseur dans le fichier
In [11]:
# lecture et affichage des 12 premiers caractères du fichier
with open('modulex.py') as f:  # opem('modulex.py', 'rt') pour forcer le mode lecture en mode textuel
    print(read(f, 1), end='')  # on lit un caractère
    # le curseur a avancé
    print(f.read(11), end='')  # on en lit 11 autres
""" Petit mo
In [12]:
# on a bien lu 12 caractères sans directement manipuler la position du curseur

Lecture du contenu ligne par ligne

In [13]:
with open('modulex.py') as f:
    for i in range(3):
        print(readline(f), end='')
""" Petit module de test pour l'importation. """

import math

Lecture de tout le contenu d'un coup

In [14]:
# readlines retourne une liste de toutes les lignes du fichier. On affiche que les 5 premières
with open('modulex.py') as f:
    print(readlines(f)[:5])
['""" Petit module de test pour l\'importation. """\n', '\n', 'import math\n', '\n', '###############################################################\n']

Relire depuis le début et déplacement

In [15]:
with open('modulex.py') as f:
    # on lit les 3 premières lignes
    print(readline(f), end='')
    print(readline(f), end='')
    print(readline(f), end='')
    
    # retour au début du fichier
    seek(f, 0)
    print(readline(f), end='')
    
    # on se place à la fin du fichier
    seek(f, 0, 2)
    print('lu: ', read(f))   # plus rien à lire
    
    # on se replace au début
    seek(f, 0)
    print('position dans le fichier: ', tell(f))
    # on se place à la fin
    seek(f, 0, 2)
    print('position dans le fichier: ', tell(f))
    
    # voir le parallèle avec la taille du fichier via ls ou  wc
""" Petit module de test pour l'importation. """

import math
""" Petit module de test pour l'importation. """
lu:  
position dans le fichier:  0
position dans le fichier:  991
In [16]:
ls -nl modulex.py
-rw-rw-r--. 1 1013 1014 991  8 mars  10:29 modulex.py
In [17]:
cat modulex.py | wc -c
991

Ecriture dans un fichier

In [18]:
ls -nl /tmp/fichier_test
ls: impossible d'accéder à '/tmp/fichier_test': Aucun fichier ou dossier de ce type
In [19]:
nom = '/tmp/fichier_test'
with open(nom, 'w') as f:
    write(f, 'Hello!')
In [20]:
cat /tmp/fichier_test
Hello!
In [21]:
# tout s'est-il bien passé ?
with open('/tmp/fichier_test') as f:
    print(readline(f))
Hello!

Lecture dans un fichier binaire

In [22]:
# lecture en mode texte
with open('/tmp/fichier_test', 'r') as f:
    print('lu: ' + read(f))
lu: Hello!
In [23]:
# lecture en mode binaire
with open('/tmp/fichier_test', 'rb') as f:
    print('lu: ' + read(f))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-23-569e9713dd8f> in <module>()
      1 # lecture en mode binaire
      2 with open('/tmp/fichier_test', 'rb') as f:
----> 3     print('lu: ' + read(f))

TypeError: Can't convert 'bytes' object to str implicitly
In [24]:
# pour manipuler les valeurs en mode fichier binaire, il faut utiliser le module struct
# et les fonctions pack et unpack
with open('/tmp/fichier_test', 'rb') as f:
    import struct
    print('lu: ', struct.unpack('<b', read(f, 1)))
lu:  (72,)
In [25]:
ord('H')
Out[25]:
72
In [26]:
# vérification par quelques commandes shell
In [27]:
! od -a -N 1 /tmp/fichier_test | head -n 1
0000000   H
In [28]:
! od -t dC -N 1 /tmp/fichier_test | head -n 1
0000000   72
In [29]:
! od -t xC -N 1 /tmp/fichier_test | head -n 1
0000000 48

Ecriture dans un fichier binaire un entier

In [30]:
with open('/tmp/fichier_test', 'wb') as f:
    import struct
    valeur = struct.pack('<b', 48)
    print('écrit: ' + str(valeur))
    write(f, valeur)
écrit: b'0'
In [31]:
! od -a -N 1 /tmp/fichier_test | head -n 1
0000000   0
In [32]:
! od -t dC -N 1 /tmp/fichier_test | head -n 1
0000000   48
In [33]:
! od -t xC -N 1 /tmp/fichier_test | head -n 1
0000000 30
In [34]:
print(ord('0'))
48
In [35]:
print(chr(48))
0
In [36]:
# ecriture de la valeur entière -1
with open('/tmp/fichier_test', 'wb') as f:
    import struct
    valeur = struct.pack('<i', -1)
    print('écrit: ' + str(valeur))
    write(f, valeur)
écrit: b'\xff\xff\xff\xff'
In [37]:
! od -a -N 4 /tmp/fichier_test | head -n 1
0000000 del del del del
In [38]:
! od -t dI -N 4 /tmp/fichier_test | head -n 1
0000000          -1
In [39]:
! od -t xI -N 4 /tmp/fichier_test | head -n 1
0000000 ffffffff

Ecrire dans un fichier un nombre réel (nombre à virgule flottante codé sur 32 bits)

In [40]:
# écriture du nombre 1.0 dans le fichier en mode binaire
with open('/tmp/fichier_test', 'wb') as f:
    import struct
    valeur = struct.pack('<f', 1.0)
    print('écrit: ' + str(valeur))
    write(f, valeur)
écrit: b'\x00\x00\x80?'
In [41]:
! od -a -N 4 /tmp/fichier_test | head -n 1
0000000 nul nul nul   ?
In [42]:
! od -t dC -N 4 /tmp/fichier_test | head -n 1
0000000    0    0 -128   63
In [43]:
! od -t xC -N 4 /tmp/fichier_test | head -n 1
0000000 00 00 80 3f
In [44]:
! od -t fF /tmp/fichier_test | head -n 1
0000000               1
In [45]:
# la valeur a bien été écrite
# Pour en être bien sûr il faut examiner le codage flottant simple précision et voir si il y a correspondance
# Ceci est valable aussi pour les entiers, selon le codage complément à 2 ou autre.