「Pythonの基礎 - ファイル」の版間の差分
514行目: | 514行目: | ||
print(p.read_text()) | print(p.read_text()) | ||
p.close() | |||
# 出力 | # 出力 | ||
519行目: | 521行目: | ||
Honda | Honda | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | |||
以下の例では、ソースコードの同階層にあるtestディレクトリにあるname.txtファイルの内容を読み込み、<br> | |||
改行文字を区切り文字として、行ごとに要素として追加したリストを作成している。<br> | |||
<syntaxhighlight lang="python"> | |||
import pathlib | |||
p = pathlib.Path('./test/name.txt') | |||
data = p.read_text() | |||
print(data.split('\n')) | |||
p.close() | |||
</syntaxhighlight> | |||
<br> | |||
==== バイナリファイルの読み書き ==== | |||
バイナリファイルに対してデータを読み書きする場合、<code>Path</code>クラスの<code>read_bytes</code>メソッドおよび<code>write_bytes</code>メソッドを使用する。<br> | |||
<br> | |||
バイナリファイルにデータを読み込む場合、パスが示すファイルの内容をbytesオブジェクトで取得する。<br> | |||
<syntaxhighlight lang="python"> | |||
Path.read_bytes() | |||
</syntaxhighlight> | |||
<br> | |||
バイナリファイルにデータを書き込む場合、パスが示すファイルに対して、引数で指定したbytesオブジェクトを書き込む。<br> | |||
<syntaxhighlight lang="python"> | |||
Path.write_bytes(data) | |||
</syntaxhighlight> | |||
<br> | |||
以下の例では、ソースコードの同階層にあるtestディレクトリにあるname.txtファイルに対して、<br> | |||
バイナリデータ(ABCDEFG)を書き込みした後、そのバイナリデータを読み込み標準出力に出力している。<br> | |||
<syntaxhighlight lang="python"> | |||
import pathlib | |||
p = pathlib.Path('./test/name.txt') | |||
p.write_bytes(b'ABCDEFG') | |||
data = p.read_bytes() | |||
print(data) | |||
p.close() | |||
# 出力 | |||
b'ABCDEFG' | |||
</syntaxhighlight> | |||
<br> | |||
また、1度に読み込むデータのバイト数を指定する場合は、従来の方法と同様、ファイルオブジェクトに対して、<code>read</code>メソッド等を使用する。<br> | |||
詳細は、[[Pythonの基礎 - ファイル#バイナリファイル]]を参照すること。<br> | |||
<br><br> | <br><br> | ||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:Python]] | [[カテゴリ:Python]] |
2021年11月21日 (日) 07:06時点における版
概要
Pythonでは、ローカルに保存されたファイルからデータを読み込んだり、ファイルへデータを書き込むことができる。
また、ディレクトリに含まれるファイルの一覧を取得したり、ディレクトリ名を変更したりすることもできる。
ファイルのオープン / クローズ
ファイルを開く
組み込み関数のopen
関数を使用してファイルを開くことができる。
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
第1引数は、開くファイル名を指定する。
正常に開くことができる場合、対応するファイルオブジェクトを返す。(ファイルオブジェクトは、第2引数で指定したモードにより異なる)
正常に開くことができない場合、例外OSError
が送出される。
第2引数は、ファイルを開くモードを指定する。(デフォルトはテキストモード(t
)のため、t
を明示的に付加する必要はない)
バイナリモード(b
)で読み込み権限や書き込み権限を付加する場合、r+b
やwb
と指定する。
- r
- 読み込み用(ファイルが存在しない場合はエラー)
- r+
- 読み込みおよび書き込み用(ファイルが存在しない場合はエラー)
- w
- 書き込み用(ファイルの中身をクリア)
- w+
- 読み込みおよび書き込み用(ファイルの中身をクリア)
- a
- 書き込み用(ファイルの末尾に追加)
- a+
- 読み込みおよび書き込み用(ファイルの末尾に追加)
- x
- 書き込み用(ファイルが存在している場合はエラー)
- x+
- 読み込みおよび書き込み用(ファイルが存在している場合はエラー)
- b
- バイナリモード
- t
- テキストモード
第4引数は、使用する文字エンコーディングを指定する。
これは、テキストモードでのみ指定する。
- ascii
- cp932
- euc_jp
- shift_jis
- utf-8 (utf_8)
エンコーディングを省略した場合は、現在のプラットフォームのデフォルトエンコーディングが使用される。
自身の環境でのデフォルトエンコーディングを確認するには、以下のソースコードを実行する。
import locale
locale.getpreferredencoding()
もし、UTF-8を使用して記述されたファイルを読み込む場合、encoding='UTF-8'
のように引数に指定する。
なお、開くファイルが存在しない場合は、例外FileNotFoundError
が発生する。
f1 = open('myfile.txt', 'r')
f2 = open('myfile.txt', 'w+')
f3 = open('myfile.txt', 'r', encoding='UTF-8')
f4 = open('myfile.txt', 'rb')
正常にファイルが開かれると、ファイルオブジェクトが返る。
ファイルオブジェクトのクラスは、open
関数で使用したモードによって異なる。
例えば、テキストモードの場合はio.TextIOWrapper
、バイナリモードの読み込みの場合はio.BufferedReader
、バイナリモードの書き込みの場合はio.BufferedWriter
、
バイナリモードの読み書きの場合はio.BufferedRandom
となる。
- r
- io.TextIOWrapper
- r+
- io.TextIOWrapper
- rb
- io.BufferedReader
- r+b
- io.BufferedRandom
- w
- io.TextIOWrapper
- w+
- io.TextIOWrapper
- wb
- io.BufferedWriter
- w+b
- io.BufferedRandom
- a
- io.TextIOWrapper
- a+
- io.TextIOWrapper
- ab
- io.BufferedWriter
- a+b
- io.BufferedRandom
- x
- io.TextIOWrapper
- x+
- io.TextIOWrapper
- xb
- io.BufferedWriter
- x+b
- io.BufferedRandom
ファイルを閉じる
ファイルの使用後は、close
関数を使用してファイルオブジェクトを閉じる。
f = open('myfile.txt', 'r')
# 処理1
# 処理2
f.close()
他の方法として、with
文を使用してファイルを開く場合、使用後は自動的にファイルを閉じることができる。
どちらの方法でも、結果は同じになる。
with open('myfile.txt', 'r') as f:
# 処理1
# 処理2
以下の例では、myfile.txtファイルの内容を読み込み画面に出力した後、ファイルオブジェクトを閉じている。
以下の内容のmyfile.txtファイルを作成する。
# myfile.txtファイル Hello World
f = open('myfile.txt', 'r')
data = f.read()
print(data)
f.close()
デキストファイルファイルの読み込み
全体を読み込む (readメソッド)
ファイルに含まれるテキストを全て読み込む場合、read
メソッドを使用する。
read(size=-1)
引数を指定しない場合、ファイルをEOF
(ファイルの終端)まで読み込み、文字列として返す。
引数に最大文字数を指定する場合、指定した文字数分だけ読み込む。
なお、読み込むファイルの文字エンコードとopen
関数で指定した文字エンコードが異なる場合、read
メソッドを実行した時、例外UnicodeDecodeError
が発生する。
以下の例では、プログラムと同階層のディレクトリにmyfile.txtファイル(UTF-8)を作成している。
f = open('myfile.txt', 'r', encoding='UTF-8')
data = f.read()
print(data)
f.close()
行単位で読み込む (readlineメソッド)
ファイルから1行ずつファイルの内容を読み込む場合、readline
メソッドを使用する。
readline
メソッドは、改行またはEOF
までファイルを読み込み、文字列として返す。
引数に最大文字数を指定する場合、指定した文字数分だけ読み込む。
ファイルの終端であるEOF
まで読み込むと空の文字列を返す。
readline(size=-1)
以下の例では、for
文およびwhile
文を使用して、ファイルの終端まで順にファイルの内容を読み込んでいる。
なお、readlines
メソッドの場合と同様、各行のデータには改行文字が含まれるため、
必要な場合は、print
関数で最後に改行を行わないようにする、または、読み込んだデータの末尾から改行を取り除くこと。
# for文を使用する場合
f = open('myfile.txt', 'r', encoding='UTF-8')
for data in f:
print(data) # 改行をそのまま出力する場合
print(data.rstrip('\n')) # 改行を取り除く場合
f.close()
# while文を使用する場合
f = open('myfile.txt', 'r', encoding='UTF-8')
while True:
data = f.readline()
if data == '':
break
print(data) # 改行をそのまま出力する場合
print(data.rstrip('\n')) # 改行を取り除く場合
f.close()
行単位で分割してリストとして取得する (readlinesメソッド)
readlines
メソッドを使用して、ファイル全体の読み込み後、読み込みしたデータを行単位で分割して、リストの要素として追加することができる。
readlines
メソッドは、引数に最大文字数を指定する場合、指定した文字数分だけ読み込む。
readlines(hint=-1)
以下の例では、ファイルの内容を全て読み込み、行単位で分割してリストとして取得したデータを順に出力している。
print
関数を使用して出力する場合、各行のデータには改行文字が含まれており、print
関数では最後に自動的に改行をするようになっているため、改行が2回出力される。
そのため、print
関数を使用して出力する場合、改行なしで出力する、または、出力するデータの末尾から改行を取り除くこと。
f = open('myfile.txt', 'r')
datalist = f.readlines()
for data in datalist:
print(data, end='') # 改行なしで出力する
print(data.rstrip('\n')) # 文字列の末尾から改行を取り除く
f.close()
テキストファイルの書き込み
テキストファイルへ書き込むためにファイルを開く場合、 open
関数のモードとしてw
、a
、x
のいずれかを指定する。
f = open('myfile.txt', 'w')
f = open('myfile.txt', 'a')
f = open('myfile.txt', 'x')
w
を指定する場合、対象のファイルが存在していない時はファイルを新規作成して書き込む。
ファイルが存在する時はファイルに上書きする。(既存のファイル内容は全て削除)
a
を指定する場合、対象のファイルが存在していない時はファイルを新規作成して書き込む。
ファイルが存在する時は既存のファイル内容に追記して書き込む。
x
を指定する場合、対象のファイルが存在しない時はファイルを新規作成して書き込む。
ファイルが存在する時は、例外FileExistsError
が発生する。
書き込むファイルの文字エンコードが、ユーザの環境のデフォルトエンコーディングと異なる場合は、文字エンコードを指定する。
f = open('myfile.txt', 'w', encoding='UTF-8')
書き込み / 上書き (wモード)
w
モードでファイルを書き込む場合、ファイルが存在しない時はファイルを新規作成、ファイルが存在する時は上書きする。(既存のファイル内容は全て削除)
テキストファイルに書き込む場合は、write
メソッドを使用する。
write
メソッドの引数に、ファイルに書き込む文字列を指定する。
write
メソッドは最後に改行を書き込まないため、必要に応じて\n
を合わせて書き込む。
標準では、\n
を書き込むと自動的に利用しているプラットフォームに合わせて改行が書き込まれる。
例えば、MacOSの場合は\r
、Windowsの場合は\r\n
が書き込まれる。
f = open('myfile.txt', 'w')
f.write('こんにちは\n')
f.close()
複数の文字列をまとめてファイルに書き込む場合は、writelines
メソッドを使用する。
引数には、文字列を要素としてリストを指定して、リストの要素を順にファイルに書き込む。
f = open('myfile.txt', 'w', encoding='UTF-8')
datalist = ['こんにちは\n', 'お元気ですか?\n', 'それではまた\n']
f.writelines(datalist)
f.close()
writelines
メソッドは自動的に改行を書き込まないため、必要に応じて、要素に格納する文字列に\n
を記述する。
w
モードの場合はファイルが存在しても上書きで書き込むため、open
関数で指定した文字エンコードを使用してファイルに書き込む。(既存のファイルの文字エンコードは無視される)
そのため、文字エンコードが異なる場合でもエラーにはならない。
追記 (aモード)
a
モードでファイルを追記する場合、ファイルが存在しない時はファイルを新規作成、ファイルが存在する時はファイルの最後に追記する。(既存の内容はそのまま)
ファイルに追記する場合は、w
モードと同様、write
メソッド、または、writelines
メソッドを使用する。
f = open('myfile.txt', 'a')
f.write('こんにちは\n')
datalist = ['お元気ですか?\n', 'それではまた\n']
f.writelines(datalist)
f.close()
※注意
既存のファイルに追記する時、ファイルの文字エンコードとopen関数の文字エンコードが異なる場合、
write
メソッドを実行する時はエラーは発生しないが文字化けするため注意すること。
f = open('myfile.txt', 'a', encoding='UTF-8')
f.write('それではまた\n')
f.close()
ファイルを新規作成して書き込む (xモード)
x
モードでファイルに書き込む場合、ファイルが存在しない場合はファイルを新規作成して書き込む。
ファイルが存在する場合は、open
関数を実行した時点で例外FileExistsError
が発生する。
ファイルに書き込む場合、w
モードと同様、write
メソッド、またはwritelines
メソッドを使用する。
f = open('myfile.txt', 'x', encoding='UTF-8')
f.write('こんにちは\n')
datalist = ['お元気ですか?\n', 'それではまた\n']
f.writelines(datalist)
f.close()
バイナリファイル
バイナリファイルを読み込む場合、open
関数のモードとしてrb
を指定する。
f = open('myfile.dat', 'rb')
バイナリファイルのデータを読み込む場合、read
メソッドを使用する。
read
メソッドの引数には、読み込むバイト数を指定する。
引数を省略した場合は、EOF
までのデータを全て読み込み、bytesオブジェクトとして返す。
read([size])
バイナリファイルへ書き込む場合、open
関数のモードとしてw
、a
、x
のいずれかにb
を加えたwb
、ab
、xb
のいずれかを指定する。
なお、w
、a
、x
の違いについてはテキストファイルの場合と同様である。
f = open('myfile.dat', 'wb')
f = open('myfile.dat', 'ab')
f = open('myfile.dat', 'xb')
バイナリファイルにデータを書き込む場合、write
メソッドを使用して、引数に指定したbytesオブジェクトをバイナリファイルに書き込む。
f = open('myfile.dat', 'wb')
f.write(b'ABCDEFG')
f.close()
f = open('myfile.dat', 'rb')
data = f.read()
print(data)
f.close()
# 出力
b'ABCDEFG'
以下の例では、画像ファイルを1バイトずつ読み込み、読み込んだデータを新規作成したバイナリファイルに書き込んでいる。
ソースコードの実行後、ソースコードと同階層のディレクトリにSample2.pngファイルが生成される。
fr = open('Sample1.png', 'rb')
fw = open('Sample2.png', 'wb')
while True:
data = fr.read(1)
if len(data) == 0:
break
fw.write(data)
fw.close()
fr.close()
ファイルの読み書き (pathlib)
Python3.4以降、pathlib
モジュールが利用できる。
Path
クラスのインスタンスを生成した後、用意されたメソッドを使用してファイルの操作を行うことができる。
Pathクラスのインスタンスを作成する
Path
クラスのインスタンスを生成するには、以下のコンストラクタを使用する。
class pathlib.Path(*pathsegments)
引数にファイルのパスを指定して、Path
クラスのインスタンスを生成する。
Path
クラスは、OSに応じてPath
クラスのサブクラスであるpathlib.WindowsPath
クラスまたはpathlib.PosixPath
クラスのインスタンスが生成される。
import pathlib
path = './test/movie'
p = pathlib.Path(path)
type(p)
なお、pathlib.WindowsPath
クラス、および、pathlib.PosixPath
クラスのコンストラクタも存在するため、明示的にインスタンスを生成することもできる。
ただし、例えば、Windows環境において、pathlib.PosixPath
クラスのインスタンスは生成できない。(例外NotImplementedError
が発生する)
class pathlib.PosixPath(*pathsegments)
class pathlib.WindowsPath(*pathsegments)
import pathlib
path = './test/movie'
wp = pathlib.WindowsPath(path)
pp = pathlib.PosixPath(path)
ファイルを開く
pathlib
モジュールを使用する場合は、Path
クラスのインスタンスを生成した後、open
メソッドを使用してファイルオブジェクトを取得する。
第1引数には、ファイルを開くモードを指定する。指定できる値は、open
関数と同様である。
第3引数には、使用する文字エンコードを指定する。これは、テキストモードでのみ指定する。指定できる値は、open
関数と同様である。
Path.open(mode='r', buffering=-1, encoding=None, errors=None, newline=None)
import pathlib
p = pathlib.Path('./test/name.txt')
f1 = p.open('r')
f2 = p.open('w+')
f3 = p.open('r', encoding='UTF-8')
f4 = p.open('rb')
Path
クラスでは、ファイルオブジェクトを使用せずにファイルの読み書きを行うことができるメソッドが存在するが、一部使用できない機能もある。
その場合は、ファイルオブジェクトを取得した上で処理を行うこと。
ファイルを閉じる
ファイルを使用した後は、close
メソッドを使用してファイルオブジェクトを閉じる。
import pathlib
p = pathlib.Path('./test/name.txt')
f = p.open('r')
# ...処理
f.close()
他の方法として、with
文を使用することにより、自動的にファイルを閉じることができる。
import pathlib
p = pathlib.Path('./test/name.txt')
with p.open('r') as f:
# ...処理1
# ...処理2
テキストファイルの読み込み
テキストファイルの全てを1度に読み込む場合、Path
クラスのread_text
メソッドを使用する。
パスが示すファイルの内容をテキストとして取得する。省略可能な第1引数には、文字エンコードを指定することがきでる。
このメソッドは、ファイルオブジェクトを取得する必要がない。
Path.read_text(encoding=None, errors=None)
import pathlib
p = pathlib.Path('./test/name.txt')
print(p.read_text())
# 出力
Yamada
Andou
Kuroki
なお、テキストファイルを行単位で読み込む場合、従来の方法と同様、ファイルオブジェクトに対してreadline
メソッド等を使用する。
import pathlib
p = pathlib.Path('./test/name.txt')
f = p.open('r')
while True:
data = f.readline()
if data == '':
break
print (data.rstrip('\n'))
# 出力
Yamada
Andou
Kuroki
テキストファイルの書き込み
テキストファイルへデータを書き込む場合、Path
クラスのwrite_text
メソッドを使用する。
第1引数は、書き込むデータを指定する。(パスが示すファイルへ書き込む)
第2引数には、省略可能であり、文字エンコーディングを指定する。
Path.write_text(data, encoding=None, errors=None)
Path
クラスのwrite_text
メソッドは、ファイルオブジェクトを取得する必要が無い。
なお、ファイルの書き込みは上書きで行われる。
また、ファイルが存在しない場合、新規作成した後でテキストの書き込みが行われる。
既存のファイルにファイル内容を追記する場合、従来の方法と同様、ファイルオブジェクトに対してwrite
メソッド等を使用する。
import pathlib
p = pathlib.Path('./test/name.txt')
p.write_text('Suzuki\nHonda\n')
print(p.read_text())
p.close()
# 出力
Suzuki
Honda
以下の例では、ソースコードの同階層にあるtestディレクトリにあるname.txtファイルの内容を読み込み、
改行文字を区切り文字として、行ごとに要素として追加したリストを作成している。
import pathlib
p = pathlib.Path('./test/name.txt')
data = p.read_text()
print(data.split('\n'))
p.close()
バイナリファイルの読み書き
バイナリファイルに対してデータを読み書きする場合、Path
クラスのread_bytes
メソッドおよびwrite_bytes
メソッドを使用する。
バイナリファイルにデータを読み込む場合、パスが示すファイルの内容をbytesオブジェクトで取得する。
Path.read_bytes()
バイナリファイルにデータを書き込む場合、パスが示すファイルに対して、引数で指定したbytesオブジェクトを書き込む。
Path.write_bytes(data)
以下の例では、ソースコードの同階層にあるtestディレクトリにあるname.txtファイルに対して、
バイナリデータ(ABCDEFG)を書き込みした後、そのバイナリデータを読み込み標準出力に出力している。
import pathlib
p = pathlib.Path('./test/name.txt')
p.write_bytes(b'ABCDEFG')
data = p.read_bytes()
print(data)
p.close()
# 出力
b'ABCDEFG'
また、1度に読み込むデータのバイト数を指定する場合は、従来の方法と同様、ファイルオブジェクトに対して、read
メソッド等を使用する。
詳細は、Pythonの基礎 - ファイル#バイナリファイルを参照すること。