Pythonでファイルを読み書きする
ファイルとは
プログラムを組んでいると以下のようなことをしたくなる時があります。
- プログラム終了後もデータをとっておきたい
- 画像などの大きいデータを扱いたい
- 他のプログラムとデータをやり取りしたい
そのような場合にデータを保存するものがファイルです。
プログラムでファイルを扱うにあたり知っておくこととして以下の4点があります
- ファイルの種類
- ファイルのパス
- 文字コード
ファイルの種類
ファイルには主に2種類あります。それはテキストファイルとバイナリファイルです。
テキスト
文字コードの形式に従っているファイルのことです。文字コードに従って保存されているため、メモ帳などのテキストエディターで開くと人間でも読んだり、編集したりすることができます。
例えばjsonやyaml、xmlなどの拡張子で保存されているファイルはテキストファイルです。
バイナリ
バイナリファイルはテキストの形式ではないファイルのことです。基本的に端末が読むためのファイルであることからテキストファイルよりもデータサイズが小さく、高速に読み書きすることができます。
ファイルのパス
プログラムでファイルを開くためにはそのファイルの場所を指定してあげる必要があります。そのファイルの場所を表す文字列のことをファイルパスと呼びます。
以下はCドライブに保存されたworkspaceというフォルダのsetting.txtというファイルのパスを表しています。
c:/workspace/setting.txt
パスを表現するときの構文は以下の通りです。
ドライブ:/ディレクトリ名1/…ディレクトリ名N/ファイル名
パスの構文についての詳細は以下になります。
- 「ドライブ名:」
この部分はどのディスクかを表しています。一般的にはCドライブですが、パソコンには複数のディスクが接続されていることがあります。そのためどのディスクかを表す必要があります。 - 「/」
ドライブやディレクトリの区切りを表しています。この区切り文字はOSによって異なっており、Windowsの場合は「\」、それ以外は「/」です。しかし、Pythonでは「/」で表現することができます。 - ディレクトリ名
フォルダとも呼ばれています。ディレクトリはファイルを整理するための仕切りのようなものです。おそらく、みなさんのお使いのパソコンでもある程度、保存したいファイルの種類に応じてフォルダを作成すると思います。 - ファイル名
ファイルの名前です。プログラムでファイルにアクセスするときは拡張子まで指定してあげる必要があります。拡張子はファイルの種類を表す文字列です。拡張子はファイル名の後ろに「.」で区切って入力されています。例でいうと「.txt」が拡張子になります。
パスの指定方法
パスを指定する方法には絶対パスと相対パスの2種類があります。それぞれパスの指定の仕方が変わってきます。
絶対パス
ドライブからファイルまでのパスをすべて指定する方法です。
c:/workspace/setting.txtは絶対パスです。
このパスの指定の仕方は絶対にその場所にファイルがあることがわかっている場合に指定します。この方法で指定するとパスの融通は利きませんが、意図しないファイルを読み込むようなこともすくなくなります。
相対パス
今プログラムが動いている位置から見たパスが相対パスです。例えばプログラムがC:/workspace/上で実行されているとすると、「setting.txt」と指定するだけでアクセスすることができます。
どこにプログラムが配置されたとしても、そのプログラムから見て決められた位置にファイルが置かれていればファイルを読み込むことができ、柔軟性があります。
エンコーディング
テキストファイルの説明をするときに文字コードに従って記述されているファイルがテキストファイルだと書きました。基本的にマシンは1と0しか表現することができません。1と0の並びが文字コード表のとおりであることがテキストファイルの条件ということです。
その文字コード表の種類を表しているのがエンコーディングです。
文字コードの種類には主にutf8、ascii、sjisなどがあります。文字コードの説明は省略しますが、一般的にはテキストファイルはutf8で表現することになっています。
ファイルを開く
ついにプログラムで同ファイルを開くのかの説明までやってきました。pythonではファイルを開くときには以下の構文でファイルを開くことができます。
with open('setting.txt',mode='r',encoding='utf8') as file:
# 読んだり書いたりする
ファイルを開くコードのポイントを説明します。
- with
プログラムでファイルを開く区間を指定するためのコードです。このネストを抜けると自動的にファイルを閉じてくれます。昨今のプログラムではめったにありませんが、プログラムでファイルを書き込みモードで開いているとその間は別のプログラムで開くことができないことがあります。できるだけ他のプログラムに影響を与えないように、プログラムでは使わなくなったらファイルを閉じるというお作法があります。
もちろんプログラムで明示的に閉じることもできますが、特に理由がなければ自動的に閉じてくれるwithを書いておくことをおススメします。 - open
これはopenという関数です。引数で指定されたファイルを読み込みます。
サンプルでは読み取り専用モードで文字コードutf8でsetting.txtを読み込もうとしています。
open関数の引数はたくさんあり、モードも複数ありますが、今回は説明を簡単にするために一部だけ紹介します。 - as file
開いたファイルにアクセスするための変数名を定義しています。withで囲った範囲ではfileという変数でアクセスすることができるようになります。
ファイルを読む
ファイルを読む方法はいくつかあります。代表的なものは以下の3つです。
サンプルをわかりやすくするために事前にsetting.txtには以下のテキストが書かれているとします。また、バイナリファイルではなくテキストファイルを読むという前提とします。
line 1
line 2
line 3
すべて読む
ファイルの内容をすべて読み込みます。ファイルの内容は一つの文字列型の値として返されます。
with open('setting.txt',mode='r',encoding='utf8') as file:
content = file.read()
print(content)
# line1
# line2
# line3
1行ずつ読む
ファイルの内容を1行ずつ読み込みます。読み込んだ行は1行ずつ配列に格納されます。
with open('setting.txt',mode='r',encoding='utf8') as file:
content_array = file.readlines()
print(content_array)
# [line 1\n, line 2\n, line 3\n]
# \nは改行を表わすエスケープ文字
ファイルに書き込む
ファイルに書き込む場合も基本的にはファイルを開いて、書き込むための関数を実行するのは変わりません。ただ、ファイルを開くときに指定するモードを「w」にする必要があります。
modeにwを書き込むと、指定したファイルがなければファイルを作成し、もしファイルが存在していれば上書きします。(前の状態が残りません)
すべて書き込む
with open('setting.txt',mode='w',encoding='utf8') as file:
file.write('hoge')
with open('setting.txt',mode='r',encoding='utf8') as file:
str = file.read()
print(str)
# hoge
1行ずつ書く
with open('setting.txt',mode='w',encoding='utf8') as file:
content_array = ['hoge','fuga']
file.writelines(content_array)
with open('setting.txt',mode='r',encoding='utf8') as file:
content = file.read()
print(content)
# hoge
# fuga
ファイルに追記したい場合
ファイルを上書きするだけでは困ってしまうと思います。そこで、末尾にファイルを追記する方法と、ファイルの一部を編集する方法を紹介します。
末尾に追記する
末尾に文章を追記するにはmodeを「a」(appendモード)で開きます。
その状態でwriteやwritelinesを呼ぶと末尾に文字列が追記されるようになります。
with open('setting.txt',mode='a',encoding='utf8') as file:
content_array = ['hoge','fuga']
file.writelines(content_array)
# line 1
# line 2
# line 3
# hoge
# fuga
途中に追記する
一度、ファイルをすべてreadlines関数で読み込みます。その後にそのファイルの内容を保存した配列を編集して、その配列の内容で上書きをします。
配列はinsertやappend関数で追記したり、好きな行の値を編集してください。
with open('setting.txt',mode='r',encoding='utf8') as file:
content_array = file.readlines()
content_array.insert(1,'fuga')
content_array.insert(1,'hoge')
content_array[3] = 'new line'
with open('setting.txt',mode='w',encoding='utf8') as file:
file.writelines(content_array)
# line 1
# hoge
# fuga
# new line
# line 3
さいごに
今回はファイルの読み書きについて解説してみました。ファイルをプログラムで扱うことができると以前に実行したときの情報を利用したプログラムを作成したり、ファイルの内容に応じてプログラムの挙動を変えるといったことも可能になります。
ファイルを扱うことができると実現できる機能に幅ができるので覚えておいて損はないはずです。