2019年2月14日木曜日

MicroPythonでファイル操作


ESP8266にMicroPythonをインストールしたのですが、Pythonに慣れていないこともあり、色々勉強中で備忘録として書いています。

MicroPythonのプログラム実行手順では、転送の度にシリアルコンソール接続を切らなければならないのが面倒で、インタラクティブモードで完結出来ないかと思いファイル操作周りだけをピックアップして記録しておく事にした次第です。
シリアルコンソールを開くまでもなく、ampy経由で実行も出来たりするんですが何だかしっくりこなかったのと、インタラクティブモードってあまり触ってないなぁ。。と思った程度なんですけどね。

以上の理由で、MicroPythonのインタラクティブモードでファイル操作してみます。

MicroPythonのDocsに従うと、OSモジュールのインポートを行う事になっていますが、
>>>import os
>>>
未入力のまま[tab]キーを押すと、
>>>
__class____name__gcmachine
uosbdev
>>>
標準で読み込まれている一覧が表示され、この中に"uos"があります。
"uos."まで入力して[tab]キーを押して、一覧表示
>>>uos.
__class____name__VfsFatchdir
duptermdupterm_notifygetcwdilistdir
listdirmkdirmountremove
renamermdirstatstatvfs
umountunameurandom
>>>uos.
OSモジュールをインポートした場合と同じメソッドが並んでいますね。

ファイルリストを表示してみましょう。
>>>uos.listdir()
['boot.py']
>>>
MicroPythonを書き込んだ状態のままなので、"boot.py"しかありません。
"main.py"もないので起動時に"OSError: [Errno 2] ENOENT"とのエラー表示が出る状態です。
と、そんな事は気にせず、ディレクトリを作成してみます。
>>>uos.mkdir('dir_test')
>>>
念のためリスト表示して確認。
>>>uos.listdir()
['boot.py', 'dir_test']
>>>
うむむ。。自分で作ったディレクトリは判るものの一週間後には、どれがディレクトリか忘れている気がします。
どうやら、"ilistdir"を使えばファイルのタイプを判別してくれるようです。
>>>uos.ilistdir()
<iterator>
>>>
イテレータです!って表示だけが返ってきたので、強引に中身を見てみます。
>>>for i in uos.ilistdir():
...print(i)
...
...
...
('boot.py', 32768, 0, 230)
('dir_test', 16384, 0, 0)
>>>
(name, type, inode[, size])の内容が表示されています。
  • name:
    文字列(dirがbytesオブジェクトの場合はbytes)で、エントリの名前です。
  • type :
    ファイルタイプを指定する整数で表示され、以下の様に判別します。
    ディレクトリ = 0x4000(16384)
    通常ファイル = 0x8000(32768)
  • inode :
    UNIX系ファイルシステムで使用されているデータ構造で、対応する整数値が表示されるそうなのですが、対応していないファイルシステムでは0となるようです。
  • size :
    sizeはファイルのサイズを表す整数です。不明の場合は-1です。
とりあえずディレクトリを見失っても何とかなりそうです。
では、作成したディレクトリ'dir_test'の中に移動してみましょう。
>>>uos.chdir('dir_test')
>>>uos.listdir()
[]
>>>
移動して、ついでにリスト表示もしてみました。
"[]"と、表示されて空っぽです。
実際に、今いるディレクトリのパスも確認してみましょう。
>>>uos.getcwd()
'/dir_test'
>>>
'dir_test'へ移動していますね。
今更ですが、この結果からすると先ほどまでの場所は'/'(ルート)とわかります。
元のディレクトリへ戻る場合は、
>>>uos.chdir('/')
>>>uos.getcwd()
'/'
>>>
もしくは、
>>>uos.chdir('..')
>>>uos.getcwd()
'/'
>>>
で移動出来ます。
では、再び'dir_test'に移動した状態でファイルを作成してみたいと思います。
>>>f = open('sample.txt', 'w')
>>>f.write('write sample')
12
>>>f.close()
>>>uos.listdir()
['sample.txt']
>>>
"sample.txt"の名称でファイルを作成し、'write sample'と言うテキストを書き込んでいます。戻り値"12"は、書き込んだテキストのバイト数です。
一応、ファイルが作成されたかも確認。
ファイルの内容を確認する場合は、
>>>f = open('sample.txt')
>>>f.read()
'write sample'
>>>f.close()
>>>
で書き込んだ内容が表示されます。
検証で作っただけなので、ファイルを削除しておきます。
>>>uos.remove('sample.txt')
>>>uos.listdir()
[]
>>>
これで元通り空っぽのディレクトリとなりました。
ルートに移動して、ディレクトリも削除します。
>>>uos.chdir('..')
>>>uos.remove('dir_test')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 21] EISDIR
>>>
エラーですね。。
ディレクトリは、"remove()"では削除できないので、以下のようにします。
>>>uos.rmdir('dir_test')
>>>
ちなみに、ディレクトリの中にファイルが入っていると、
>>>uos.rmdir('dir_test')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 13] EACCES
>>>
とエラー表示が出て削除出来ないので注意しましょう。
とは言え、このモードで使う人はあまりいないと思いますけど。

最後に、メモ書きとしてMicroPythonでデフォルトでimport可能なモジュールの一覧。
>>>help('modules')
__main__ http_client socket upip
_boot http_client_ssl ssd1306 upip_utarfile
_onewire http_server ssl upysh
_webrepl http_server_ssl struct urandom
apa102 inisetup sys ure
array io time urequests
binascii json uasyncio/__init__ urllib/urequest
btree lwip uasyncio/core uselect
builtins machine ubinascii usocket
collections math ucollections ussl
dht micropython ucryptolib ustruct
ds18x20 neopixel uctypes utime
errno network uerrno utimeq
esp ntptime uhashlib uzlib
example_pub_button onewire uheapq webrepl
example_sub_led os uio webrepl_setup
flashbdev port_diag ujson websocket
framebuf random umqtt/robust websocket_helper
gc re umqtt/simple zlib
hashlib select uos
Plus any modules on the filesystem
>>>

0 件のコメント:

コメントを投稿