Pythonでファイルをコピーする方法4選: copyfile, copy, copy2, copytree
- 作成日: 2021-06-02
- 更新日: 2023-12-24
- カテゴリ: Python
Pythonでファイルをコピーする方法
Pythonではライブラリを使うとファイルを簡単にコピーすることができます。
ライブラリはshutilという標準ライブラリを使います。
この記事ではshutilの関数を使ってファイルをコピーする方法を解説します。
結論から言うとファイルのコピーは↓のようにします。
import shutil
shutil.copyfile('sample/src/file1.txt', 'sample/dst/file2.txt')
shutil.copy('sample/src/file1.txt', 'sample/dst/file3.txt')
shutil.copy2('sample/src/file1.txt', 'sample/dst/file4.txt')
shutil.copytree('sample/src/', 'sample/dst/src')
# sample/dst/
# ├── file2.txt
# ├── file3.txt
# ├── file4.txt
# └── src
# └── file1.txt
具体的には↓を見ていきます。
- 主要4関数の違い
- copyfile()の使い方
- copy()の使い方
- copy2()の使い方
- copytree()の使い方
関連記事
頭が悪い人のPythonのevalの使い方
頭がいい人のPythonのexitの使い方
自作関数read_fileでファイルを読み込み【ファイル入出力, コマンド】
状態遷移による文字列パースのテクニック【Python】
形態素解析で代名詞+助詞+名詞を文章から抜き出す【Python, 自然言語処理, Janome】
主要4関数の違い
copyfile()
, copy()
, copy2()
, copytree()
の違いを具体的に表にしてみました。
関数名 | コピーするもの | コピーの挙動 |
copyfile |
ファイル | ファイル内容のみをコピーし、ファイルのパーミッション、メタデータをコピーしない。 |
copy |
ファイル | ファイル内容をコピーし、パーミッションもコピーする。 |
copy2 |
ファイル | ファイル内容をコピーし、パーミッションやメタデータ(作成日、更新日)もコピーするように努める。 |
copytree |
ディレクトリ | ディレクトリを丸ごとコピーする。 |
とりあえず何でもかんでもコピーしたい場合はcopy2()
を使っておけば良さそうです。
ただcopy2()
も絶対的にメタデータのコピーが成功するという訳ではないみたいなので、その辺は注意が必要です。
それからできるだけ完璧にディレクトリをコピーしたい場合はcopytree()
の引数(copy_function
)にcopy2
を指定すれば良さそうです。
メタデータやパーミッションが重要でない場合はcopyfile()
のほうがcopystat()
を呼び出さない分動作は早くなりそうです。
copyfile()の使い方
shutil.copyfile()
は第1引数に指定されたファイルを第2引数にコピーします。
copyfile()
の構造は↓のようになっています。
shutil.copyfile(src, dst, *, follow_symlinks=True)
第2引数のdst
は書き込み可能である必要があります。
dst
が書き込み不可であった場合、copyfile()
は例外OSError
を送出します。
dst
がすでに存在する場合は上書きされます。
第3引数のfollow_symlinks
がFalse
でsrc
がシンボリックリンクであった場合、copyfile()
はsrc
の内容をコピーせずシンボリックリンクを作成します。
copyfile()
はcopy()
やcopy2()
と違ってコピー時にファイルのパーミッションやメタデータを維持しません。
そのため日付などはコピー元と異なる場合があります。
↓がサンプルコードです。
import shutil
shutil.copyfile('sample/src/file1.txt', 'sample/dst/file2.txt')
↑の場合sample/src/file1.txt
というファイルがsample/dst/file2.txt
にコピーされます。
copy()の使い方
shutil.copy()
は第1引数に指定されたファイルを第2引数にコピーします。
copy()
は↓のような構造になっています。
shutil.copy(src, dst, *, follow_symlinks=True)
copy()
もcopyfile()
と同様に第3引数のfollow_symlinks
がFalse
でsrc
がシンボリックだった場合は、単純にシンボリックリンクを作成します。
copy()
はファイルの内容の他に、ファイルのパーミッションをコピーします。
ファイルの作成日や更新日などのメタデータはコピーしません。
↓がサンプルコードです。
import shutil
shutil.copy('sample/src/file1.txt', 'sample/dst/file2.txt')
↑の場合もsample/src/file1.txt
というファイルがsample/dst/file2.txt
にコピーされます。
copy2()の使い方
shutil.copy2()
は第1引数に指定されたファイルを第2引数にコピーします。
copy2()
の構造は↓のようになっています。
shutil.copy2(src, dst, *, follow_symlinks=True)
copy2()
も第3引数にfollow_symlinks
を持っていますが、これがFalse
でsrc
がシンボリックリンクだった場合は、単純にシンボリックリンクが作成されます。
copy2()
はメタデータをコピーしようとします。
メタデータとはファイルの作成日、更新日などのデータのことです。
copy2()
はこれらのデータのコピーのために内部的にcopystat()
を使います。
↓がサンプルコードです。
import shutil
shutil.copy2('sample/src/file1.txt', 'sample/dst/file2.txt')
↑の場合もsample/src/file1.txt
というファイルがsample/dst/file2.txt
にコピーされます。
copytree()の使い方
ディレクトリを丸ごとコピーしたい場合はcopytree()
を使います。
copytree()
は第1引数に指定されたディレクトリを第2引数にコピーします。
copytree()
は↓のような構造になっています。
shutil.copytree(
src,
dst,
symlinks=False,
ignore=None,
copy_function=copy2,
ignore_dangling_symlinks=False,
dirs_exist_ok=False,
)
src
がコピー元でdst
がコピー先です。
サンプルコードは↓です。
import shutil
shutil.copytree('sample/src/', 'sample/dst/src')
symlinks
がTrue
の場合は、ディレクトリ内のシンボリックリンクは、そのままシンボリックリンクとしてコピーされます。
symlinks
がFalse
の場合は、シンボリックリンクであっても中身をコピーして新しくディレクトリを作成します。
ignore
には関数を指定します。この関数の返り値のファイル名をcopytree()
はコピー時に無視します。
この関数の第1引数には現在走査中のディレクトリを表すオブジェクト、第2引数にはディレクトリの内容を表すオブジェクトが渡されます。
この関数の挙動は↓のようなコードで確認することができます。
def ignore(dir_, lis):
print(dir_, lis)
return 'file1.txt'
shutil.copytree('sample/src/', 'sample/dst/src', ignore=ignore)
出力結果↓。
sample/src/ {'file1.txt', 'dir1', 'dir2'}
<DirEntry 'dir1'> {'file1.txt', 'file2.txt'}
<DirEntry 'dir2'> {'file1.txt', 'file2.txt'}
↑のコードを実行するとsample/src
以下のファイルがコピーされます。
そのときfile1.txt
は除外してコピーされます。
copy_function
にはコピーで使用する関数を指定します。デフォルトではcopy2()
です。
copyfile()
を指定する場合は↓のようになり、
shutil.copytree('sample/src/', 'sample/dst/src', copy_function=shutil.copyfile)
copy()
を指定する場合は↓のようになります。
shutil.copytree('sample/src/', 'sample/dst/src', copy_function=shutil.copy)
symlinks
がFalse
で、シンボリックリンクが壊れている場合はコピーに失敗し例外がエラーリストに追加される場合がありますが、ignore_dangling_symlinks
をTrue
に設定するとこのエラーが送出されなくなります。
dirs_exist_ok
がTrue
の場合、すでにディレクトリが存在する場合でもエラーが送出されなくなります。
copytree()
はコピー先にすでにディレクトリが存在する場合は、dirs_exist_ok
が指定されている場合を除いてエラー(FileExistsError
)が出力されます。
try:
shutil.copytree('sample/src/', 'sample/src')
except FileExistsError as e:
print(e)
# [Errno 17] File exists: 'sample/src'
おわりに
今回はPythonでファイルをコピーする方法を見てみました。
コピーはプログラムの基本ですが、Pythonではshutil
を使うことで簡単に行うことができます。
🦝 < コピーがコピーを生み
🐭 < コピーの海……