Python 3でFTPを使ったファイルのアップロード

[タグ] FTP python [日付] 2009/12/20 11:39 (Sun)

Python 3でFTPを使ってテキストファイルをアップロードする方法のメモ.

FTP通信の準備

PythonでFTPを使うには標準ライブラリである「ftplib」を用いる.ftplibには「FTP」というクラスがあり,コンストラクタで次のようにホストに接続できる.

ftp = FTP(hostname, username, passwd)

hostnameは接続先のホスト名,usernameはユーザ名,passwdはパスワードを表している.これでFTPでファイルをアップロードする準備ができた.

FTPのコマンド

FTPで通信を行うには,FTPのコマンドを指定してやる必要がある.今回使うのは以下の2つ.

STOR remote-filename
STORコマンドは,ファイルをアップロードするためのコマンド.remote-filenameの部分にアップロード先でのファイル名を指定する.
SITE site-specific-command
SITEコマンドは,標準で定義されていないアップロード先のサーバ特有のコマンドを送信する.パーミッションを設定するときにこのコマンドを使う.

ファイルのアップロード

実際にテキストファイルをアップロードするには,次のようにする.

ftp.storlines("STOR /public/index.html", f)

ここでfは,あらかじめオープンしておいたファイル.storlines()がファイルをアップロードするためのメソッドで,ASCIIモードでファイルを送信する.バイナリモード用のstorbinary()というメソッドもあるが,今回は使わない.第1引数に指定しているのがSTORコマンドで,上の例ではfで指定されたファイルをpublicというディレクトリにindex.htmlというファイル名でアップロードしている.

ファイルのオープン

ファイルのオープンについて注意しなければならないのは,次のようにファイルをバイナリモードで開かなければならない点.

f = open("index.html", "rb")

storlines()では,fから文字列を1行読み込んで改行をCR+LFに変換しながらアップロードを行っている.その際に改行はバイト列として定義されたもの(b'\r\n')が使われているので,fもバイナリモードで開かないとf.readline()したときに文字列が返ってきてしまい,エラーになる.

ftplib.pyのFTP.storlines()の実装(Python 3.1.1)
B_CRLF = b'\r\n'

def storlines(self, cmd, fp, callback=None):
    self.voidcmd('TYPE A')
    conn = self.transfercmd(cmd)
    while 1:
        buf = fp.readline()
        if not buf: break
        if buf[-2:] != B_CRLF:
            if buf[-1] in B_CRLF: buf = buf[:-1]
            buf = buf + B_CRLF
        conn.sendall(buf)
        if callback: callback(buf)
    conn.close()
    return self.voidresp()

パーミッションの変更

UNIX系サーバの場合,ファイルのパーミッションの変更が必要になる場合がある.それにはFTPクラスのsendcmd()というメソッドを使う.

ftp.sendcmd("SITE CHMOD 604 /public/index.html")

sendcmd()は単に第1引数で指定されたコマンドを送信するだけのメソッド.上の例では,publicディレクトリのindex.htmlというファイルのパーミッションを604に変更している.SITEコマンドはサーバ特有のコマンドを送信するためのコマンドなので,UNIX系サーバでは上の方法で大丈夫だと思うが,他のOSだと別の方法が必要になるかも.

まとめ

from ftplib import FTP

ftp = FTP(hostname, username, passwd)
f = open("index.html", "rb")
ftp.storlines("STOR /public/index.html", f)
f.close()
ftp.sendcmd("SITE CHMOD 604 /public/index.html")
ftp.close()

参考

  1. ftplib(Python v3.1.1 documentation) [2010/3/3 18:20]
  2. Raw FTP Command List [2010/3/3 18:18]

コメント

名前:
captcha:
[前の記事] [次の記事]