Pythonの基礎 - ファイル

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動

概要

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+bwbと指定する。

  • 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関数のモードとしてwaxのいずれかを指定する。

 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関数のモードとしてwaxのいずれかにbを加えたwbabxbのいずれかを指定する。
なお、waxの違いについてはテキストファイルの場合と同様である。

 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()