この記事ではPythonのファイルをコピーする関数『shutil.copy()』と『shutil.copy2()』について、
shutil.copy()
とshutil.copy2()
とはshutil.copy()
とshutil.copy2()
の構文shutil.copy()
とshutil.copy2()
の使い方- ファイルを既存のディレクトリにコピーする方法
- ファイルをコピー元のファイルに置き変える
shutil.copy()
とshutil.copy2()
の注意点- 第2引数
dst
で新規のディレクトリパスを指定しても、ディレクトリは作成されない - 存在しない中間ディレクトリを第2引数
dst
で指定するとエラーになる
- 第2引数
shutil.copy()
とshutil.copy2()
の違い
などをサンプルコードを用いて分かりやすく説明するように心掛けています。ご参考になれば幸いです。
shutil.copy()とshutil.copy2()とは
shutil.copy()
とshutil.copy2()
は、Pythonの標準ライブラリshutil
に含まれる関数で、ファイルの内容をコピーするために使用されます。shutil.copy()
とshutil.copy2()
では、メタデータ(作成日時や更新日時)の扱い方が異なります。
shutil.copy()
- メタデータはコピーしません。
shutil.copy2()
- 可能な限りメタデータもコピーします。
shutil.copy()
よりも詳細なコピーを行うのがshutil.copy2()
です。
- 可能な限りメタデータもコピーします。
後ほどshutil.copy()
とshutil.copy2()
の構文や使い方について詳しく説明しますが、まず以下に示す簡単なサンプルコードを見てみましょう。
import shutil
# コピー元ファイルパス
src_file = 'temp/file.txt'
# コピー先ディレクトリパス
dst_dir = 'temp/dir1/'
# shutil.copy()でファイルをコピー
shutil.copy(src_file, dst_dir)
# shutil.copy2()でファイルをコピー(メタデータもコピーされる)
shutil.copy2(src_file, dst_dir)
上記のサンプルコードでは、temp/file.txt
をtemp/dir1
にコピーしています。shutil.copy2()
を使用すると、メタデータもコピーするようになります。
公式ドキュメント
shutil.copy()
とshutil.copy2()
の公式ドキュメントのリンクを以下に示します。
この記事ではshutil.copy()
とshutil.copy2()
の「使い方」や「注意点」についてできる限り分かりやすく説明しています。これらの関数の詳細を知りたい方は、公式ドキュメントをご覧ください。
shutil.copy()とshutil.copy2()の構文
shutil.copy()
とshutil.copy2()
の構文を以下に示します。
構文
shutil.copy(src, dst)
shutil.copy2(src, dst)
shutil.copy()
とshutil.copy2()
の引数と返り値を以下に示します。
引数
src
- コピー元のファイルパスです。
dst
- コピー先のファイルパスまたはディレクトリパスです。
dst
がディレクトリパスを指定している場合には、コピー元のファイルはdst
の中にコピーされます。- ファイル名は
src
で指定したファイルパスのファイル名となります。
- ファイル名は
dst
がファイルパスを指定している場合には、コピー元のファイルはdst
の中にコピーされます。- ファイル名は
dst
で指定したファイルパスのファイル名となります。
- ファイル名は
dst
が既に存在しているファイルパスを指定している場合には、そのファイルがコピー元のファイルに置き換えられます。
返り値(戻り値)
- 新しく作成したファイルのパスを返します。
shutil.copy()とshutil.copy2()の使い方
以下のディレクトリ構造とします。
temp/
├── dir1/
├── dir2/
│ └── file.txt
└── file.txt
このディレクトリ構成で、shutil.copy()
とshutil.copy2()
について、以下に示している使い方をこれから説明します。
- ファイルを既存のディレクトリにコピーする(dstでディレクトリパスを指定した場合)
- ファイルを既存のディレクトリにコピーする(dstでファイルパスを指定した場合)
- ファイルをコピー元のファイルに置き変える(dstで既に存在しているファイルパスを指定した場合)
上記の使い方について順番に説明します。
ファイルを既存のディレクトリにコピーする(dstでディレクトリパスを指定した場合)
shutil.copy()
とshutil.copy2()
の第2引数dst
にディレクトリパスを指定すると、コピー元のファイルはdst
の中にコピーされます。その際、ファイル名はsrc
で指定したファイルパスのファイル名となります。
サンプルコード
import shutil
src_file = 'temp/file.txt'
dst_dir = 'temp/dir1/'
shutil.copy(src_file, dst_dir)
上記のサンプルコード実行後のディレクトリ構成
temp/
├── dir1/
│ └── file.txt ← 「temp/file.txt」が「temp/dir1/」の中にコピーされる
├── dir2/
│ └── file.txt
└── file.txt
なお、コピー元のファイルと同名のファイルがdst
に存在している場合には、そのファイルがコピー元のファイルに置き換えられます。
サンプルコード
import shutil
src_file = 'temp/file.txt'
dst_dir = 'temp/dir2/'
shutil.copy(src_file, dst_dir)
上記のサンプルコード実行後のディレクトリ構成
temp/
├── dir1/
├── dir2/
│ └── file.txt ← コピー元のファイル(temp/file.txt)に置き換えられる
└── file.txt
ファイルを既存のディレクトリにコピーする(dstでファイルパスを指定した場合)
shutil.copy()
とshutil.copy2()
の第2引数dst
にファイルパスを指定すると、コピー元のファイルはdst
の中にコピーされます。その際、ファイル名はdst
で指定したファイルパスのファイル名となります。
サンプルコード
import shutil
src_file = 'temp/file.txt'
dst_file = 'temp/dir1/copied_file.txt'
shutil.copy(src_file, dst_file)
上記のサンプルコード実行後のディレクトリ構成
temp/
├── dir1/
│ └── copied_file.txt ← 「temp/file.txt」がdstで指定したファイルパスのファイル名(copied_file.txt)でコピーされる
├── dir2/
│ └── file.txt
└── file.txt
ファイルをコピー元のファイルに置き変える(dstで既に存在しているファイルパスを指定した場合)
shutil.copy()
とshutil.copy2()
の第2引数dst
に既に存在しているファイルパスを指定すると、そのファイルがコピー元のファイルに置き換えられます。
サンプルコード
import shutil
src_file = 'temp/file.txt'
dst_file = 'temp/dir2/file.txt'
shutil.copy(src_file, dst_file)
上記のサンプルコード実行後のディレクトリ構成
temp/
├── dir1/
├── dir2/
│ └── file.txt ← コピー元のファイル(temp/file.txt)に置き換えられる
└── file.txt
shutil.copy()とshutil.copy2()の注意点
shutil.copy()
とshutil.copy2()
の注意点を以下に示します。
dst
で新規のディレクトリパスを指定しても、ディレクトリは作成されない- 存在しない中間ディレクトリを
dst
で指定するとエラーになる
各注意点について順番に説明します。
dstで新規のディレクトリパスを指定しても、ディレクトリは作成されない
shutil.copy()
とshutil.copy2()
の第2引数dst
に新規のディレクトリパスを指定しても、ディレクトリは作成されません。例えば、temp/dir3
と指定すると、temp/dir3
の中にファイルがコピーされるのではなく、dir3
というファイルとしてコピーされるので注意してください。
サンプルコード
import shutil
src_file = 'temp/file.txt'
dst_path = 'temp/dir3'
shutil.copy(src_file, dst_path)
上記のサンプルコード実行後のディレクトリ構成
temp/
├── dir1/
├── dir2/
│ └── file.txt
├── file.txt
└── dir3 ← 「temp/file.txt」がdir3というファイルとしてコピーされる
なお、temp/dir3/
と/
を付けると、指定するとエラーになります。
サンプルコード
import shutil
src_file = 'temp/file.txt'
dst_path = 'temp/dir3/'
shutil.copy(src_file, dst_path)
エラーメッセージ
OSError: [Errno 22] Invalid argument: 'temp/dir3/'
存在しない中間ディレクトリをdstで指定するとエラーになる
shutil.copy()
とshutil.copy2()
の第2引数dst
に存在しない中間ディレクトリがあると、エラーになります。例えば、temp/dir1/new_dir/file.txt
のように指定するとエラーになります。dir1
にnew_dir
という中間ディレクトリが作成され、その中にfile.txt
というファイル名でコピー元ファイルがコピーされるわけではありません。
サンプルコード
import shutil
src_file = 'temp/file.txt'
dst_path = 'temp/dir1/new_dir/file.txt'
shutil.copy(src_file, dst_path)
上記のサンプルコード実行後に期待するディレクトリ構成(実際はこうならない)
temp/
├── dir1/
│ └── new_dir/
│ └── file.txt ← コピーされたファイル
├── dir2/
│ └── file.txt
└── file.txt
エラーメッセージ
FileNotFoundError: [Errno 2] No such file or directory: 'temp/dir1/new_dir/file.txt'
shutil.copy()とshutil.copy2()の違い
shutil.copy2()
の使い方はshutil.copy()
と同じですが、メタデータ(作成日時・更新日時など)の扱いが異なります。
shutil.copy()
- メタデータをコピーしません。例えば、コピーしたファイルの更新日時はコピーした時刻となります。
shutil.copy2()
- メタデータをできる限りコピーします。コピー元とコピー先の更新日時が同じになります。
サンプルコード
import shutil
import os
src_file = 'temp/file.txt'
dst_file_copy1 = 'temp/dir1/copied_file_copy1.txt'
dst_file_copy2 = 'temp/dir1/copied_file_copy2.txt'
# shutil.copy()でコピー
shutil.copy(src_file, dst_file_copy1)
# shutil.copy2()でコピー
shutil.copy2(src_file, dst_file_copy2)
# 更新日時の確認
print('src:', os.path.getmtime(src_file))
print('copy:', os.path.getmtime(dst_file_copy1))
print('copy2:', os.path.getmtime(dst_file_copy2))
上記のサンプルコードを実行すると、shutil.copy()
でコピーしたファイルの更新日時はコピーした時刻となり、shutil.copy2()
でコピーしたファイルの更新日時は元のファイルと同じであることが確認できます。
なお、shutil.copy2()
でもすべてのメタデータが保持されるわけではないので注意してください。
高水準のファイルコピー関数 (
shutil.copy()
,shutil.copy2()
) でも、ファイルのメタデータの全てをコピーすることはできません。POSIXプラットフォームでは、これはACLやファイルのオーナー、グループが失われることを意味しています。 Mac OSでは、リソースフォーク(resource fork)やその他のメタデータが利用されません。これは、リソースが失われ、ファイルタイプや生成者コード(creator code)が正しくなくなることを意味しています。 Windowsでは、ファイルオーナー、ACL、代替データストリームがコピーされません。
shutil
--- 高水準のファイル操作
本記事のまとめ
この記事ではPythonのファイルをコピーする関数『shutil.copy()』と『shutil.copy2()』について、以下の内容を説明しました。
shutil.copy()
とshutil.copy2()
とはshutil.copy()
とshutil.copy2()
の構文shutil.copy()
とshutil.copy2()
の使い方- ファイルを既存のディレクトリにコピーする方法
- ファイルをコピー元のファイルに置き変える
shutil.copy()
とshutil.copy2()
の注意点- 第2引数
dst
で新規のディレクトリパスを指定しても、ディレクトリは作成されない - 存在しない中間ディレクトリを第2引数
dst
で指定するとエラーになる
- 第2引数
shutil.copy()
とshutil.copy2()
の違い
お読み頂きありがとうございました。