今回はフォルダ、及びファイル操作の関数(メソッド)の中で、使用頻度が高そうなものを選んで解説したいと思います。
これさえ知っていれば、一般的なプログラムで困ることは無いでしょう。
フォルダ、ファイル操作をするための準備
C#の場合、参照設定として System.IO を指定する必要がありますが、Pythonの場合、import ステートメントで必要なモジュールを指定します。
一般的によく使う機能については、次の3つのモジュールに含まれています。
import os
import shutil
import glob
フォルダ操作一覧
以下がフォルダ操作関連のメソッドです。
osクラスを使ってフォルダを削除する場合、空のフォルダでないと削除できませんが、shutilクラスを使うと中身が空でなくとも削除可能です。
尚、windows の場合、フォルダのパスの区切りは '\' ではなく '/' を使います。
例えば、'd:\document\myfolder' と記述するとエラーになるため、'd:/document/myfolder' という具合に指定します。
| 機能 | 記述例 | 備考 |
|---|---|---|
| フォルダの作成 | os.mkdir('myfolder') | フォルダが存在しない場合はエラーとなる。 |
| フォルダの存在確認 | os.path.exists('myfolder') | 有れば True 、無ければ False。 |
| フォルダか否かの確認 | os.path.isdir('myfolder') | フォルダなら True、ファイルならFalse。 |
| フォルダの削除 | os.rmdir('myfolder') | 存在しないフォルダ、又は空でないフォルダ を指定するとエラーとなる。 |
| フォルダ名の変更 | os.rename('oldname','newmame') | 第1引数で指定した名前を、第2引数で 指定した名前に変更する。 変更後の名前が存在するとエラーとなる。 |
| フォルダ配下ごと削除 | shutil.rmtree('myfolder') | 存在しないフォルダを指定するとエラー となる。 |
| フォルダ配下ごとコピー | shutil.copytree('path1','path2') | 第1引数にコピー元、第2引数にコピー先 のフォルダを指定。 コピー先が存在している場合はエラーとなる。 |
| フォルダ配下ごと移動 | shutil.move('path1','path2') | 存在しないフォルダを指定するとエラー となる。 フォルダ名の変更にも使える。 |
ファイル操作一覧
os クラスで指定するパスの区切りは '/' でないとエラーになりますが、glob なら '\' と '/' のどちらでも使用可能です。
| 機能 | 記述例 | 備考 |
|---|---|---|
| ファイル一覧の取得 | os.listdir('path') | 指定したフォルダ直下のファイル及びフォルダが取得可能。 |
| ファイルの存在確認 | os.path.exists('path') | ファイルが存在すればTure、存在しなければFalse。 |
| ファイルか否かの 確認 | od.path.isfile('path') | ファイルの場合はTrue,ファイルではない場合はFalse。 |
| ファイルの削除 | os.remove('path') | ファイルが存在しなければエラーとなる。 |
| パスをファイル名と 拡張子に分割して取得 | os.path.splitext('path') | パスを拡張子とそれ以外に分割し、タプルとして返す。 'e:/document/test.csv' ⇒ ('e:/document/text','.csv') 尚、拡張子にはピリオドが含まれる。 |
| ファイル名のみ 取得 | os.path.basename('path') | 'e:/document/test.csv' ⇒ 'test.csv' |
| フォルダ名のみ 取得 | os.path.dirname('path') | 'e:/document/test.csv' ⇒ 'e:/document' |
| ファイル一覧を 階層ごと取得 | glob.glob('path') | 末端の階層まで下って全てのファイルとフォルダを取得。 パスにはワイルドカード(*や?) が指定可能。 glog.glob('e:/document/*.csv') glog.glob('e\document\*.csv') |
ファイルのオープンと読み書き
ファイルにデータを書き込んだり、ファイルからデータを読み込むには次のメソッドを使います。
| ファイルオープン | open(ファイル名,モード,エンコード文字) | open('test.csv','w',encoding='shift-jis') モードには、書込:'w'、追加:'a'、読込:'r' バイナリ:'b'、読み書き両方:'r+' がある。 モード省略時は 'a' となる。 エンコード省略時は 'utf-8'となる。 |
| 一括読み込み | read() | ファイルを丸ごと読み込んで、 1つの文字列として返す。 |
| 一括読み込み | readlines() | ファイルを丸ごと読み込んで、 行ごとに分割し、リストとして返す。 各要素には改行コードが付加される。 |
| 1行読み込み | readline() | ファイルから1行読み込む |
| 一括書き込み | write(文字列) | 引数で指定された文字列を書き込む。 1行ごと改行したい場合は文字列の末尾に 改行コード(/n)を付加する。 |
| 一括書き込み | writelines(文字列のリスト) | リストの要素を一括して書き込む。 各要素の末尾に改行コードは付加されない。 |
| バッファの 書き込み | flush() | バッファに残っている内容を全て書き込む。 |
| ファイルを閉じる | close() | ファイルを閉じる。 |
では、それぞれ具体的なサンプルコードを見ていきましょう。
----------------------------------------
#ファイルを丸ごと読み込む
----------------------------------------
f = open('test.txt','r')
data = f.read()
f.close()
----------------------------------------
#ファイルを行に分割して読み込む
----------------------------------------
f = open('test.txt','r')
data = f.readlines()
f.close()
----------------------------------------
#ファイルをループで読み込む
----------------------------------------
f = open('test.txt','r')
while True:
data = f.readline()
print(data)
if not data :
break
f.close()
----------------------------------------
#文字列を丸ごと書き込む
----------------------------------------
f = open('test.txt','w')
data = f.write('abcdefg')
f.close()
----------------------------------------
#リストを丸ごと書き込む
----------------------------------------
f = open('test.txt','w')
f.writelines(['aaa','bbb','ccc'])
f.close()
ファイルから1行づつ読み込む場合、ファイルの終わり(EOF)を判定する必要があります。
Python では、ファイルの終わりに達した場合 readline() が空文字を返してくるため、これを利用します。
if not data と記述することで、data が空文字('')であることを判定しています。
他に、if len(data) == 0 とか、if data == '' という風に書くことも可能です。
with を使って closeを省略する
open したら必ず close しなければなりませんが、これを省略する書き方があります。
with open(ファイル名,モード,エンコード文字) as 変数名 :
if や for 文と同様、コロン(:)で終わっているので、次行以降はこのステートメントの影響下に入ります。
C#でいうところの using(var sr = new StreamReader(~){ ・・・・} みたいなもんですね。
先ほどのファイル読み書きのサンプルコードを with を使って書き直すと、次のようになります。
----------------------------------------
#ファイルを丸ごと読み込む
----------------------------------------
with open('test.txt','r') as f:
data = f.read()
----------------------------------------
#ファイルを行に分割して読み込む
----------------------------------------
with open('test.txt','r') as f:
data = f.readlines()
----------------------------------------
#ファイルをループで読み込む
----------------------------------------
with open('test.txt','r') as f:
while True:
data = f.readline()
print(data)
if not data :
break
----------------------------------------
#文字列を丸ごと書き込む
----------------------------------------
with open('test.txt','w') as f:
f.write('abcdefg')
----------------------------------------
#リストを丸ごと書き込む
----------------------------------------
with open('test.txt','w') as f:
writelines(['aaa','bbb','ccc'])
readlines の注意点
readline は行ごとに分割してくれる便利なメソッドですが、各リストの末尾に改行コードが付加されてしまいます。
この改行コードを取り除くには、文字列クラスの strip メソッドを使います。
#末尾に改行コードが含まれたリスト
data = ['今日はいい天気だ/n','明日も晴れるかな/n']
#前後の空白及び制御文字を削除
data[0] = data[0].strip()
data[1] = data[1].strip()
writelines の注意点
writelines はリストを丸ごとファイルに書き込んではくれますが、要素毎に改行を付加してくれません。
例えば、f.writelines(['aaa','bbb','ccc']) と記述すると、ファイルには 'aaabbbccc' の1行が書き込まれます。
C#の File.WriteAllLines の場合、自動的に改行を付けて書き込んでくれますが、それと同じだと考えると期待を裏切られますのでご注意ください。
例えば、バックスラッシュ( \n ) を要素の末尾に追加して、次のように記述します。
with open('test.txt','w') as f:
writelines(['aaa\n','bbb\n','ccc\n'])
まとめ
今回は、フォルダとファイル操作について、一通りの説明を行いました。
C#で用意されている機能は、当然ながらPython でも一通り用意されています。
逆に、フォルダ単位でのコピーや移動など、C#には無い便利な機能も存在しています。
ファイル、フォルダ操作に関してはPythonの方が充実している印象を受けました。
writelines や readlines など、同じような名前で同じような機能がC#にもありますが、改行コードの扱いが若干違いますので、その点は注意が必要ですが、それ以外はすんなり入れたのではないでしょうか。
バイナリファイルの扱いについては使用頻度が低いので今回は省略しましたが、それ以外は良く使うものばかりなので、是非とも参考にしてPythonライフを楽しんでいただければと思います。
コメント