naritoブログ

このブログはDjangoとBootstrap4で作成されました
ソースコード

Python、shutilでファイル、ディレクトリ操作

プログラミング関連 shutilモジュール Python 約428日前
2016年6月14日23:05


shutil モジュールはファイルやファイルの集まりに対する高水準の操作方法を多数提供します。
特にファイルのコピーや削除のための関数が用意されています。
個別のファイルに対する操作については、 os モジュールも参照してください。



高水準の操作ということで、単純なopen()等を使った操作よりも簡単に行うことができます。
以下は、a.pyというファイルをa2.pyというファイル名でコピーして作成します。
既にa2.pyが存在していた場合は、上書きします。
import shutil

# (コピー元, コピー先)
shutil.copyfile("a.py", "a2.py")


もちろん、絶対パスでも指定できます。
import os
import shutil

current_dir = os.path.dirname(os.path.abspath(__file__))
read_path = os.path.join(current_dir, "a.py")
write_path = os.path.join(current_dir, "a2.py")
shutil.copyfile(read_path, write_path)


コピー先がディレクトリの場合は、copyfileではなくcopyを使います。
この場合、folerAの中にa.pyがコピーされます。
通常のファイル→ファイルへのコピーもできるので、とりあえずこの.copy()を使っておけば間違いないです。
import shutil
shutil.copy("a.py", "folderA")



copyfileobjという、ファイルではなくファイル形式のオブジェクトを扱う関数もあります。
これは、Helloと書かれたfile.pyが出来上がります。
import shutil
from io import StringIO

fsrc = StringIO("Hello")
with open("file.py", "w") as fdst:
    shutil.copyfileobj(fsrc, fdst)


ByteIOバージョンはこうです。
import shutil
from io import BytesIO

fsrc = BytesIO(b"Hello")
with open("file.py", "wb") as fdst:
    shutil.copyfileobj(fsrc, fdst)


copyfileobjをrequestsと一緒に使い、ダウンロード等もできます。
import shutil
import requests

url = "ttps://torina.top/media/images/98265c87e5d0395a96056d3e7f711a6d_m.jpg"
res = requests.get(url, stream=True)
with open("test.jpg", "wb") as fdst:
    shutil.copyfileobj(res.raw, fdst)


copytreeを使うと、ディレクトリを丸ごとコピーできます。
import shutil

shutil.copytree("folderA", "folderC")


rmtreeを使うと、ディレクトリ丸ごと削除です。
import shutil

shutil.rmtree("folderC")


moveは、ファイル又はディレクトリを別の場所に移動します。
移動先がディレクトリとして存在していれば、元srcがファイルでもディレクトリでも、移動先のディレクトリの中に入れてくれます。
移動先がファイルとして存在していた場合、元srcがディレクトリの指定ならばエラー。元srcがファイルならば上書きします。

import shutil

shutil.move("a.py", "b.py")
shutil.move("folderA", "folderB")


zipなどのアーカイブ化操作も可能です。
これは、カレントディレクトリのZIPが作成されます。current.zipです。
import shutil

shutil.make_archive("current", "zip")


カレントディレクトリに、与えられたパスのzipを作成したい、という処理を考えてみます。
まず、このようなディレクトリの構成です。main.pyが、作成するファイルになります。


Aの中は、ファイルが2つ


Bの中は、ディレクトリとファイルが1つ


更にCは、ファイルが2つあります。


このように、相対パスか絶対パスで指定すると...
    make('A')
    make(r'C:\MyMercurial\test\testpython\shu\B')
    make('B\C')


カレントにA、B、Cそれぞれのアーカイブができて


中身も、それぞれ大丈夫そうですね。
A.zipの中み


B.zipの中身



C.zipの中身



コードは以下になります。
"""shutilモジュールの、make_archiveのテスト"""
import os
import shutil


def make(target, kind='zip'):
    """与えられたファイル・ディレクトリを圧縮する

    引数:
        target: 圧縮したいファイル・ディレクトリ。相対、フル、どちらもOK
        kind: 圧縮の種類。デフォルトでzip
    """

    current = os.getcwd()
    head, tail = os.path.split(target)
    base_name = os.path.join(current, tail)
    root_dir = os.path.join(current, head)
    base_dir = tail

    shutil.make_archive(
        base_name, kind, root_dir=root_dir, base_dir=base_dir)


if __name__ == '__main__':
    make('A')
    make(r'C:\MyMercurial\test\testpython\shu\B')
    make('B\C')



http://docs.python.jp/3/library/shutil.html