Maison >développement back-end >Tutoriel Python >Partager des conseils sur l'utilisation efficace du traitement des opérations d'E/S de fichiers en Python
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 '你好'
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()
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 'mmap.mmap'> # 可以通过索引获取内容 >>> 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
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
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!