Pythonでファイルの作成と削除|ファイル操作

python_file_operation_pc Python
python_file_operation_pc

はじめに

プログラムを書いているとファイルの操作を行う事は多いかと思います。

ファイルを読み込んだり書き込んだり、上書きしたり追記したり。

書き方は色々あるかと思いますが、一通り把握できれば安心ですね。

ファイルの操作を行うときは、open()を使ってもファイルの作成や読み込み、書き込み、上書き等はできますが、close()するのを忘れてしまう可能性がありますので、なるべくwithステートメントを使う方が良いかと思います。

withステートメントを使えばわざわざクローズする処理を書かずに済みますし、インデント内の処理が終われば自動的にクローズしてくれるので楽です。

空ファイルの作成

空ファイルを作成するにはpathlibモジュールを使用します。

# 空ファイルの作成
import pathlib

f = pathlib.Path('sample.txt')
f.touch()

プログラムを実行すると、空ファイルのsample.txtが作成されたかと思います。

ファイルの作成(書き込み)

ファイルに書き込むにはwithステートメントを使ってファイル名を指定し、モードを書き込み・上書きモードである「w」にします。

# ファイルの書き込み
with open('sample.txt', 'w') as f:
    f.write('Hello!')

プログラムを実行するとsample.txtが作成されます。

中身を確認すると、f.write()で指定した内容が書き込まれている事が確認できるかと思います。

ただ、1バイト系の文字列ならこのままでも問題はないですが、日本語のような2バイト系を書き込む際はこのままだと文字化けしてしまいます。

# エンコードを指定しないと文字化けが起こる
text_data = """
今日の天気は晴れですが、
明日は雨になるみたいです。
"""

with open('sample.txt', 'w') as f:
    f.write(text_data)

プログラムを実行すると、ファイルに書き込まれた文字列は文字化けしています。。

これを回避するには、codecsモジュールを使用します。

# エンコードを指定し、文字化けを防ぐ
import codecs

text_data = """
今日の天気は晴れですが、
明日は雨になるみたいです。
"""

# 書き込み
with codecs.open('sample.txt', 'w', 'utf-8') as f:
    f.write(text_data)

# 読み込み
with codecs.open('sample.txt', 'r', 'utf-8') as f:
    print(f.read())
        
#出力結果
今日の天気は晴れですが、
明日は雨になるみたいです。

問題なく日本語表示できました。

日本語を使う場合は気を付ける必要がありますね。

ファイルの追記

ファイルの追記をしたい場合はwithステートメントを使い、追記モードである「a」を指定します。

text_data = """
TEST1
TEST2
TEST3
"""

# 一旦、書き込み
with open('sample.txt', 'w') as f:
    f.write(text_data)

# 追記
with open('sample.txt', 'a') as f:
    f.write("AAA")

# 読み込み
with open('sample.txt', 'r') as f:
    print(f.read())


# 出力結果
TEST1
TEST2
TEST3
AAA

ファイルの削除

ファイルを削除するにはosモジュールをインポートし、os.remove()を使用します。

import os

if os.path.exists('sample.txt'):
    print("ファイルを削除します。")
    os.remove('sample.txt')

# 出力結果
ファイルを削除します。

一旦、ファイルを削除すると復元は難しいので注意しましょう。

もしくは、os.unlink()を使います。

import os

if os.path.exists('sample.txt'):
    print("ファイルを削除します。")
    os.unlink('sample.txt')

ファイルをコピーする

Pythonでファイルやフォルダをコピーするには、shutil(shell utilities)モジュールを使用します。

単純に同じディレクトリ内にコピー&ペーストしたい場合は以下になります。

import shutil

# ファイルをコピー(同じディレクトリ内にコピーする場合)
src_file = 'C:\\test1_dir\\sample01.txt'
dst_file = 'C:\\test1_dir\\sample02.txt'
print(shutil.copy(src_file, dst_file))

# 出力結果
"""
C:\test1_dir\sample02.txt
"""

戻り値は、ペースト先のフルパス(絶対パス)になります。

仮にコピー先に同一ファイル名があってもそのまま上書きされます。

下記のようにペースト後のファイル名を省略した場合は、エラーになります。

Windowsのように同一ディレクトリ内にコピペしたら「sample01 – コピー.txt」のようにはならないということですね。

プログラムではあまりこのような書き方はしないと思いますが念のため。

import shutil


# file copy(同じフォルダ内にコピーする場合)
src_file = 'C:\\test1_dir\\sample01.txt'
dst_file = 'C:\\test1_dir'
print(shutil.copy(src_file, dst_file))

# 出力結果
"""
shutil.SameFileError: 'C:\\test1_dir\\sample01.txt' and 'C:\\test1_dir\\sample01.txt' are the same file
"""

ファイルを異なるディレクトリにコピーする

異なるディレクトリにコピー&ペーストしたい場合は、第二引数にディレクトリのパスを指定してあげます。

この場合、コピーしたファイル名がそのまま使われます。

import shutil


# ファイルのコピー(異なるディレクトリにコピーする場合)
src_file = 'C:\\test1_dir\\sample01.txt'
dst_dir = 'C:\\test2_dir\\'
print(shutil.copy(src_file, dst_dir))

# 出力結果
"""
C:\test2_dir\sample01.txt
"""

戻り値はペースト後のフルパスになります。

もちろん、ペースト先のディレクトリが存在しない場合はエラーになります。

import shutil

# ファイルのコピー(異なるディレクトリにコピーする場合)
src_file = 'C:\\test1_dir\\sample01.txt'
dst_dir = 'C:\\test2_dir\\'
print(shutil.copy(src_file, dst_dir))

# 出力結果
"""
OSError: [Errno 22] Invalid argument: 'C:\\test2_dir\\'
"""

下記のようにディレクトリの存在確認をしてから処理させましょう。

import shutil
import os

src_file = 'C:\\test1_dir\\sample01.txt'
dst_dir = 'C:\\test2_dir\\'
if not os.path.exists(dst_dir):
    print("ディレクトリが存在しないので作成します。")
    os.mkdir(dst_dir)
    print(shutil.copy(src_file, dst_dir))

# 出力結果
"""
ディレクトリが存在しないので作成します。
C:\test2_dir\sample01.txt
"""

ファイル名を変更して異なるディレクトリにコピーする

ファイル名を変更して異なるディレクトリにコピー&ペーストする場合は、第二引数にファイル名までを記載します。

import shutil

src_file = 'C:\\test1_dir\\sample01.txt'
dst_file = 'C:\\test2_dir\\new_file.txt'
print(shutil.copy(src_file, dst_file))

# 出力結果
"""
C:\test2_dir\new_file.txt
"""

簡単ですね。

まとめ

どのプログラム言語を使っていてもファイルの操作は必須だと思いますので、ある程度忘れずに覚えておきたいところです。

仮に忘れてしまってもググればいいだけですので、その都度調べていく形でも自然に覚えるのではないでしょうか。

もう少しこのコンテンツも肉付けしたいと思っていますので、時間を見つけて追記していきたいと思います。

コメント

タイトルとURLをコピーしました