Python で効率的なファイル I/O 操作処理を使用するためのヒントを共有する

高洛峰
リリース: 2017-03-16 16:16:25
オリジナル
1376 人が閲覧しました

テキストファイルの読み書き方法は?

実際のケース

特定のテキストファイルのエンコード形式が変更されました(UTF-8、GBK、BIG5など)。これらのファイルをpython2.xとpython3.xでそれぞれ読み取るにはどうすればよいですか?

解決策

python2とpython3の違いを区別することに注意してください

stringのセマンティクスが変更されました:

python2 python3
str バイト
ユニコード ストラ


python2.xはファイルを書き込む前にUnicodeをエンコードし、ファイルを読み取った後にバイナリ文字列をデコードします

>>> 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')
ログイン後にコピー

Hello

python3.xはオープン時にfunctiontのテキストモードを指定し、encodingはエンコード形式を指定します

>>> 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
'你好'
ログイン後にコピー

ファイルバッファリングの設定方法

実際のケース

ファイルの内容をハードディスクデバイスに書き込む場合、このタイプの I/O 操作は、I/O 操作の回数を減らすために使用されます。 , ファイルは通常、バッファーを使用します (システム呼び出しは、十分なデータがある場合にのみ実行されます)。 Python でファイルオブジェクトのバッファリングコンテキストを設定するにはどうすればよいですか?

解決策完全なバッファリング: open 関数のバッファリングは 1 より大きい整数

n に設定されます。n はバッファ サイズです

>>> f = open('demo2.txt', 'w', buffering=2048)
>>> f.write('+' * 1024)
>>> f.write('+' * 1023)
# 大于2048的时候就写入文件
>>> f.write('-' * 2)
>>> f.close()
ログイン後にコピー
行バッファリング: open 関数のバッファリングは 1 に設定されます

>>> f = open('demo3.txt', 'w', buffering=1)
>>> f.write('abcd')
>>> f.write('1234')
# 只要加上\n就写入文件中
>>> f.write('\n')
>>> f.close()
ログイン後にコピー
バッファリングなし: オープン関数のバッファリングは 0 に設定されています
>>> f = open('demo4.txt', 'w', buffering=0)
>>> f.write('a')
>>> f.write('b')
>>> f.close()
ログイン後にコピー
ファイルをメモリにマップするにはどうすればよいですか?

実際のケース

一部のバイナリ ファイルにアクセスする場合、ランダム アクセスを実現するためにファイルをメモリにマップできることが望まれます (フレームバッファ デバイス ファイル)。一部の組み込みデバイスでは、レジスタがメモリ アドレス空間にアドレス指定されます。 /dev/mem の特定の範囲をマップしてこれらのレジスタにアクセスできます

複数のプロセスが同じファイルにマップする場合、プロセス通信の目的も達成できます

解決策

標準の m

map

モジュールを使用しますライブラリ mmap() 関数。パラメーターとして開いているファイル記述子が必要です

次のようなファイルを作成します

[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'
ログイン後にコピー
View

[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
ログイン後にコピー
スライスを変更します
>>> m[4:8] = '\xff' * 4
ログイン後にコピー
View

[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
ログイン後にコピー
View

[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
ログイン後にコピー

ステータス

にアクセスする方法ファイル?

実際のケース

一部のプロジェクトでは、次のようなファイルのステータスを取得する必要があります:

ファイルの種類 (通常のファイル、ディレクトリ、シンボリックリンク、デバイスファイル...)

ファイルのアクセス権限

ファイルの最後のアクセス/変更/ノードステータス変更時間

通常のファイルのサイズ

…..

解決策

現在のディレクトリには以下のファイルがあります

[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
ログイン後にコピー
システムコール

osモジュールの下に3つのシステム

標準ライブラリ内 stat、fstat、lstatを呼び出してファイルのステータスを取得します

>>> 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
ログイン後にコピー
ファイルのアクセス許可を取得します。0より大きい限りtrueです

>>> s.st_mode & stat.S_IRUSR
256
>>> s.st_mode & stat.S_IXGRP
0
>>> s.st_mode & stat.S_IXOTH
0
ログイン後にコピー
ファイルの変更時刻を取得します

# 访问时间
>>> s.st_atime
1486197100.3384446
# 修改时间
>>> s.st_mtime
1486197100.3384446
# 状态更新时间
>>> s.st_ctime
1486197100.3384446
ログイン後にコピー
取得したタイムスタンプを変換

>>> 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)
ログイン後にコピー
通常のファイルサイズを取得

>>> s.st_size
0
ログイン後にコピー
ショートカット関数

標準ライブラリのos.path以下の一部の関数はより簡潔に使用できます

ファイルタイプ判定

>>> os.path.isdir('dirs') 
True
>>> os.path.islink('lockfile')
True
>>> os.path.isfile('files') 
True
ログイン後にコピー
ファイル3回

>>> os.path.getatime('files')
1486197100.3384445
>>> os.path.getmtime('files')
1486197100.3384445
>>> os.path.getctime('files')
1486197100.3384445
ログイン後にコピー
ファイルサイズを取得する

>>> os.path.getsize('files') 
0
ログイン後にコピー
一時ファイルの使い方は?

実際のケース

あるプロジェクトでは、1Gごとにデータを収集し、データ分析を行い、そのような大きな一時データがメモリに常駐している場合、最終的に分析結果のみを保存します。これらの一時データを保存するには、一時ファイル (外部ストレージ) を使用できます

一時ファイルには名前を付ける必要はなく、閉じた後に自動的に削除されます

解決策

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'
ログイン後にコピー

以上がPython で効率的なファイル I/O 操作処理を使用するためのヒントを共有するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート