Arduino詳解その30です。前回の記事はこちらです。 hirocom777.hatenadiary.org
ファイルとフォルダー
前回はSDカードのファイルからデータを読み出してみました。今回は、SDカード上のファイルやフォルダーの取り扱いについて見てみようと思います。
今回は、以下のスケッチをご紹介します。
#include <SPI.h> #include <SD.h> File root; void setup() { //初期設定 Serial.begin(9600); SD.begin(4); root = SD.open("/"); //一番上(ルート)の中を表示 printDirectory(root, 0); } void loop() { } void printDirectory(File dir, int numTabs) { while (true) { //フォルダー内の次のファイル File entry = dir.openNextFile(); if (! entry) { break;//オープンする内容が無ければループを抜ける } for (uint8_t i = 0; i < numTabs; i++) { Serial.print('\t'); } //ファイル(フォルダー)名の表示 Serial.print(entry.name()); if (entry.isDirectory()) { //フォルダーならフォルダーの中を表示 Serial.println("/"); printDirectory(entry, numTabs + 1); } else { //ファイルサイズの表示 Serial.print("\t\t"); Serial.println(entry.size(), DEC); } entry.close();//終わったら呼び出し先に戻る } }
このスケッチは、ArduinoIDEに標準でついてくるスケッチ例⇒SD⇒listfilesからコメント、補助的処理などを省いて簡略化したものです。SDカードのフォルダー、ファイルの配置状況を教えてくれます。さっそく実行してみましょう。今回はSDカードの内容を以下の様にしてみました。(Windows 10のPCで設定しました。)
D:. │ TEXT_1.txt │ TEXT_2.txt │ ├─FOLDER_1 │ │ TEXT_3.txt │ │ TEXT_4.txt │ │ │ └─FOLDER_2 │ TEXT_6.txt │ TEXT_5.txt │ └─FOLDER_3 TEXT_8.txt TEXT_7.txt
実行してみる
SDカードをSDカードシールドに実装した状態で上記のスケッチを書き込み、実行してみてください。シリアルモニターを開いてみると・・・。僕の場合は以下の様に表示されました。
SYSTEM~1/ WPSETT~1.DAT 12 INDEXE~1 76 TEXT_1.TXT 0 FOLDER_1/ FOLDER_2/ TEXT_6.TXT 0 TEXT_5.TXT 0 TEXT_3.TXT 0 TEXT_4.TXT 0 FOLDER_3/ TEXT_8.TXT 0 TEXT_7.TXT 0 TEXT_2.TXT 0
先頭の3行はWindowsが作成したシステムファイルですので無視してください。ちょっと順番が異なりますが、表示は合っていますね。ファイル名の後に書いてある数字はファイルサイズです。今回は空のファイルを配置したので全部ゼロになっています。
スケッチの解説
それではスケッチの解説です。まずはsetupから。SD.open()は以前出てきました。ファイルをオープンするためのものですが、今回はカッコの中が"/"となっています。これは、ストレージ(今回の場合はSDカード)の一番上のフォルダーをさしています。SD.open()はフォルダーを開くこともできるのです。まずは一番上を開いてrootに割り当てています。その後にあるprintDirectory()って何なんでしょ?
printDirectory()
printDirectory()は、フォルダーを指定してその中にあるファイル、フォルダーの一覧をシリアルモニターに表示する関数です。表示の対象がファイルの場合、ファイル名の後にファイルのサイズを表示します。表示の対象がフォルダーの場合、フォルダー名を表示した直後に表示フォルダーメイド体を指定して、さらにprintDirectory()を呼び出します。すると、そのファルダー内のファイル、フォルダーの一覧を表示して・・・となって、すべての階層についてファイル、フォルダーの一覧を表示すると言う訳です。いわゆる再帰というやつです。
呼び出しの際にフォルダーとともに数値が指定されていますが、これは階層の深さによって表示の先頭に指定数のタブを配置することでインデント(段落)表示をしているんですね。表示する内容がなくなると、終了して呼び出し先に戻ります。
今回新しく出てきたものはこちらです。
* FileObject.openNextFile()
ファイルオブジェクトで指定したフォルダーに存在する次のファイル(フォルダー)をファイルオブジェクトの形で返します。対象がない場合は、falseを返します。カッコの中の引数は、FILE_READ(読込モード、ファイルの先頭から処理する)、FILE_WRITE(読込、書込モード、ファイルの最後から処理する)の2つを選択できます。省略するとFILE_READとなります。
* FileObject.isDirectory()
ファイルオブジェクトがフォルダーかどうかを判定します。フォルダーならばtrue、そうでなければfalseを返します。
* FileObject.name()
ファイルオブジェクトの名前を返します。
* FileObject.size()
ファイルオブジェクトのサイズを返します。単位はバイトです。
SDカードの様子が分かった!!
いかがでしたでしょうか?これでSDカードの内容を把握する方法がわかってきたと思います。次回も引き続きファイルやフォルダーの取り扱いについてご紹介しようと思います。お楽しみに!!