Maison  >  Article  >  développement back-end  >  Partager des conseils sur l'utilisation efficace du traitement des opérations d'E/S de fichiers en Python

Partager des conseils sur l'utilisation efficace du traitement des opérations d'E/S de fichiers en Python

高洛峰
高洛峰original
2017-03-16 16:16:251373parcourir

Comment lire et écrire des fichiers texte ?

Cas réel

Un certain format d'encodage de fichier texte a été modifié (comme UTF-8, GBK, BIG5), comment l'utiliser dans python2.x et python3.x respectivement Lire ces fichiers ?

Solution

Faites attention à la différence entre python2 et python3

La sémantique de la chaîne a changé :

python2 python3
str bytes
unicode str


python2.x encode l'Unicode avant d'écrire le fichier et décode la chaîne binaire après avoir lu le fichier

>>> f = open('py2.txt', 'w')
>>> s = u'你好'
>>> f.write(s.encode('gbk'))
>>> f.close()
>>> f = open('py2.txt', 'r')
>>> t = f.read()
>>> print t.decode('gbk')

Bonjour

ouvrir en python3.x Fonction spécifie le mode texte de t, l'encodage spécifie le format d'encodage

>>> f = open('py3.txt', 'wt', encoding='utf-8')
>>> f.write('你好')
2
>>> f.close()
>>> f = open('py3.txt', 'rt', encoding='utf-8')
>>> s = f.read()
>>> s
'你好'

Comment définir le tampon du fichier

Cas réel

Écrire le contenu du fichier dans le disque dur Lors de l'utilisation d'un périphérique, des appels système sont utilisés. Ce type d'opération d'E/S prend beaucoup de temps. Afin de réduire le nombre d'opérations d'E/S, les fichiers utilisent généralement des tampons (uniquement lorsqu'il y a suffisamment de données à effectuer). appels système) et le cache de fichier Comportement , divisé en mise en mémoire tampon complète, mise en mémoire tampon de ligne et aucune mise en mémoire tampon.

Comment définir le contexte de buffering du fichier objet en Python ?

Solution

Mémoire tampon complète : La mise en mémoire tampon de la fonction open est définie sur un entier n supérieur à 1, n est la taille du tampon

>>> f = open('demo2.txt', 'w', buffering=2048)
>>> f.write('+' * 1024)
>>> f.write('+' * 1023)
# 大于2048的时候就写入文件
>>> f.write('-' * 2)
>>> f.close()

line Buffering : Le buffering de la fonction open est défini sur 1

>>> f = open('demo3.txt', 'w', buffering=1)
>>> f.write('abcd')
>>> f.write('1234')
# 只要加上\n就写入文件中
>>> f.write('\n')
>>> f.close()

Pas de buffering : Le buffering de la fonction open est défini sur 0

>>> f = open('demo4.txt', 'w', buffering=0)
>>> f.write('a')
>>> f.write('b')
>>> f.close()

Comment mapper les fichiers à la mémoire ?

Cas réels

Lors de l'accès à certains fichiers binaires, on espère que les fichiers pourront être mappés en mémoire pour obtenir un accès aléatoire (fichier de périphérique framebuffer)

Certains périphériques d'intégration. , les registres sont adressés à l'espace d'adressage de la mémoire, nous pouvons mapper une certaine plage de /dev/mem pour accéder à ces registres

Si plusieurs processus sont mappés sur le même fichier, la communication des processus peut également être réalisée

Solution

Utiliser la fonction mmap() du module mmap de la bibliothèque standard, qui nécessite un descripteur de fichier ouvert en paramètre

Créer le fichiers suivants

[root@pythontab.com ~]# dd if=/dev/zero of=demo.bin bs=1024 count=1024
1024+0 records in
1024+0 records out
1048576 bytes (1.0 MB) copied, 0.00380084 s, 276 MB/s
# 以十六进制格式查看文件内容
[root@pythontab.com ~]# od -x demo.bin 
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
4000000
>>> import mmap
>>> import os
>>> f = open('demo.bin','r+b')
# 获取文件描述符
>>> f.fileno()
3
>>> m = mmap.mmap(f.fileno(),0,access=mmap.ACCESS_WRITE)
>>> type(m)
<type &#39;mmap.mmap&#39;>
# 可以通过索引获取内容
>>> m[0]
'\x00'
>>> m[10:20]
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
# 修改内容
>>> m[0] = '\x88'

Afficher

[root@pythontab.com ~]# od -x demo.bin 
0000000 0088 0000 0000 0000 0000 0000 0000 0000
0000020 0000 0000 0000 0000 0000 0000 0000 0000
*
4000000

Modifier les tranches

>>> m[4:8] = '\xff' * 4

Afficher

[root@pythontab.com ~]# od -x demo.bin 
0000000 0088 0000 ffff ffff 0000 0000 0000 0000
0000020 0000 0000 0000 0000 0000 0000 0000 0000
*
4000000
>>> m = mmap.mmap(f.fileno(),mmap.PAGESIZE * 8,access=mmap.ACCESS_WRITE,offset=mmap.PAGESIZE * 4) 
>>> m[:0x1000] = '\xaa' * 0x1000

Afficher

[root@pythontab.com ~]# od -x demo.bin 
0000000 0088 0000 ffff ffff 0000 0000 0000 0000
0000020 0000 0000 0000 0000 0000 0000 0000 0000
*
0040000 aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
*
0050000 0000 0000 0000 0000 0000 0000 0000 0000
*
4000000

Comment accéder au statut d'un fichier ?

Cas réel

Dans certains projets, nous avons besoin d'obtenir l'état du fichier, tel que :

Le type de fichier (fichier ordinaire, répertoire, lien symbolique, fichier de périphérique ...)

Droits d'accès au fichier

Heure du dernier accès/modification/changement d'état du nœud du fichier

Taille générale du fichier

…..

Solution

Le répertoire actuel contient les fichiers suivants

[root@pythontab.com 2017]# ll
total 4
drwxr-xr-x 2 root root 4096 Sep 16 11:35 dirs
-rw-r--r-- 1 root root 0 Sep 16 11:35 files
lrwxrwxrwx 1 root root 37 Sep 16 11:36 lockfile -> /tmp/qtsingleapp-aegisG-46d2-lockfile

Appel système

Trois systèmes sous le module os dans le bibliothèque standard Appelez stat, fstat, lstat pour obtenir l'état du fichier

>>> import os
>>> s = os.stat('files')
>>> s
posix.stat_result(st_mode=33188, st_ino=267646, st_dev=51713L, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1486197100, st_mtime=1486197100, st_ctime=1486197100)
>>> s.st_mode
33188
>>> import stat
# stat有很多S_IS..方法来判断文件的类型
>>> stat.S_ISDIR(s.st_mode)
False
# 普通文件
>>> stat.S_ISREG(s.st_mode)
True

Obtenez l'autorisation d'accès au fichier, qui est vraie tant qu'elle est supérieure à 0

>>> s.st_mode & stat.S_IRUSR
256
>>> s.st_mode & stat.S_IXGRP
0
>>> s.st_mode & stat.S_IXOTH
0

Obtenez l'heure de modification du fichier

# 访问时间
>>> s.st_atime
1486197100.3384446
# 修改时间
>>> s.st_mtime
1486197100.3384446
# 状态更新时间
>>> s.st_ctime
1486197100.3384446

Convertissez le horodatage obtenu

>>> import time
>>> time.localtime(s.st_atime)
time.struct_time(tm_year=2016, tm_mon=9, tm_mday=16, tm_hour=11, tm_min=35, tm_sec=47, tm_wday=4, tm_yday=260, tm_isdst=0)

Obtenez la taille du fichier ordinaire

>>> s.st_size
0

Fonction de raccourci

Bibliothèque standard Certaines fonctions sous os.path sont plus concises à utiliser

Type de fichier Judge

>>> os.path.isdir('dirs') 
True
>>> os.path.islink('lockfile')
True
>>> os.path.isfile('files') 
True

Fichier trois fois

>>> os.path.getatime('files')
1486197100.3384445
>>> os.path.getmtime('files')
1486197100.3384445
>>> os.path.getctime('files')
1486197100.3384445

Obtenir la taille du fichier

>>> os.path.getsize('files') 
0

Comment utiliser les fichiers temporaires ?

Cas réel

Dans un certain projet, nous collectons des données à partir de capteurs après la collecte de chaque 1G de données, nous effectuons une analyse des données et, en fin de compte, ne sauvegardons les résultats de l'analyse que si des données temporaires aussi volumineuses. est stocké de manière permanente La mémoire consommera beaucoup de ressources mémoire. Nous pouvons utiliser des fichiers temporaires pour stocker ces données temporaires (stockage externe)

Les fichiers temporaires n'ont pas besoin d'être nommés et seront automatiquement supprimés après la fermeture.

Solution

Utiliser TemporaryFile, NamedTemporaryFile

>>> from tempfile import TemporaryFile, NamedTemporaryFile
# 访问的时候只能通过对象f来进行访问
>>> f = TemporaryFile()
>>> f.write('abcdef' * 100000)
# 访问临时数据
>>> f.seek(0)
>>> f.read(100)
'abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd'
>>> ntf = NamedTemporaryFile()
# 如果要让每次创建NamedTemporaryFile()对象时不删除文件,可以设置NamedTemporaryFile(delete=False)
>>> ntf.name
# 返回当前临时文件在文件系统中的路径
'/tmp/tmppNvNA6'
sous tempfile dans la bibliothèque standard

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn