|
ファイルの書き込み
Step-1
とりあえずは新規のファイルだけを対象としておこう。まずはファイル作成だ。ここで対象とするファイルシステムは、本編でも登場したFAT12というもので、FDのファイルシステムとして広く知られている。このファイルシステムでは、1ファイル辺り32バイト、224個の管理領域が存在する。ここから空き領域を探し出して、必要な情報を書き込んで完了だ。クラスター番号については、FAT領域から空きを検索する関数を作成して取得、設定する。ファイルの更新時刻については、システム時刻(時計機能で実装)をフォーマットして設定する。この領域は微妙なビットの使い方をしているのでちょっと面倒だ。確認のためのdirコマンドではファイル時刻は出力されないので、適当に入れちゃってもいいのだが、律儀なrapperはちゃんと入れておいた(笑。ファイルオープンとクローズのAPIおよびファイルを作成するだけのアプリを作成して、Let's実行!!・・・dirコマンドで確認。で、できとる(笑。
0バイトの謎のファイルが出現!!
Step-2
ファイルの作成に成功したrapperは次の任務に移ることにする。ファイルへの書き込みだ。(というか、これが本来の目的でした・・・) うむ、書き込みの場合は、何バイト(もしくは何Kバイト、何Mバイト)書き込まれるか予想ができない。さて、バッファの容量はどうしよう。考えていても仕方ないので、とりあえず4Kバイトのバッファを作成して、都度使い回すことにしよう。読み込みの際にしても、ものずごく大きなファイルを扱うときに、ファイルオープンで長時間待ち状態になることを考えれば、そのうち有効な機能になるに違いない(多分。このため、ファイルハンドル構造体にいくつか項目を追加した。バッファサイズ、現在のバッファ中の位置、現在のクラスター番号、ファイル情報がそれだ。バッファサイズについては、アプリ強制終了時のファイルクローズで必要となるので、現行のファイルオープン時にも設定する。それ以外については設定する必要はない。(新しいファイル機能でのみで設定します)
準備ができたところで、実際の書き込みを実装していこう。バッファが4Kバイトなので、書き込み容量が4Kバイトになるまではバッファにためておく。4Kバイトになったところで、ディスクイメージの領域に書き込む。これを繰り返し、余った部分はファイルクローズ時に書き込む、という仕様にした。ディスクイメージ領域への書き込みでは、512バイト毎にクラスターを検索して書き込んでいく。書き込みが完了したら、FATのクラスター番号に0xfffを格納して、書き込みサイズを返す。APIの方では書き込めた容量を確認し、要求に満たない場合は、それ以上書き込みを要求しない様にした。それでは、sosu3をファイルに出力する様に改造して、テスト実行&tviewで確認・・・ぉぉ書けてるっぽい。
見えるぞ、私にもファイルが見える・・・(古。
Step-3
さぁて、書き込みにも無事成功したところで、もう少し踏み込んでみよう。Step-2までは新規ファイルのみ対象だったのだが、既存のファイルも対象にしてみよう。管理領域から指定ファイルを探して、存在すればそのファイルに対して処理を施す。ここでは、書き込むときのモードを以下の2種類用意することにする。ファイルを空にしてから書き込むモードと既存のデータに追加して書き込むモードだ。ファイルを空にする方は新規とさほど変わらない。オープンするときにファイルサイズを0バイトにしておくことを忘れない様にするくらいだ。一方、追加モードについては、書き込む位置を特定するため、ファイルの読み飛ばし(というより、クラスターの特定)をおこなう必要があるので、関数を作成して対応する。また、作成している機能では、ディスク領域への書き込みが512バイト単位になっているので、余りの部分はバッファに読み込んでおくことにする。この分だけバッファ内の現在の位置を進めておくことを忘れない様にする。最後にファイルサイズを書き込むときに、余りの部分を足してしまわない様に気を付けなければばらない。それでは、追加モードで書き込むアプリを作成して、sosu3実行&追加実行&tviewで確認・・・あい、無事追加できた様です。
今更でなんですが、4Kバイトのバッファって読み込みに対応できるんだろうか・・・。圧縮に対応しようとすると、結局別のバッファが必要なわけで、意味なくなっちゃうような気が・・・。非対応って手もないことはないんだけど、最初から圧縮されているファイルもあるわけで・・・。だんだん「北の○から」口調になってきたので、この辺にしておいて、今のところは、読み込みは既存の機能を使ってね、って感じです(汗。
6バイト追加されています。手で書き加えたんじゃないよ(笑。
Step-4
ではでは本格的にディスクに書いちゃいましょうかね。と、まった!!大事なことを忘れています。FATですFAT。なんとなく、今までの流れでFATの情報が更新できている様な気がしてたんだけど、更新していたのは、扱いやすい様に圧縮を解いて保持していた情報に過ぎない。今までどおりメモリの中だけで処理をするなら、この情報しか使わないので問題ないが、実際にディスクに書き出すには、ちゃんとイメージの方を更新しておく必要があるのだ。処理としては、冒頭のFAT圧縮を解く処理の逆の処理をする。具体的には、2つのクラスタ番号から3バイトのデータを作り出して、該当の位置に格納する。これを関数化し、クラスタ番号を更新している場所で呼び出す様にした。では実行をば・・・バラバラ(表示の音)、ちゃんとFAT内容が更新できた模様です。
ちょっと解説。下の画像なんですが、(3行目c0から)470〜487番のクラスタ内容を表示しています。「sosu.txt」は475〜487番のクラスタに連続して書かれています。474が0xfffで終わっていて、475が0x1dc(476)、次が0x1dd(477)と続いて、487が0xfffで終わっています。これはイメージ上の0x0200から始まるFATを表示していますが、もう一方の0x1400から始まるFATも同様に更新しています。うむ、正しく更新完了です。
イメージ中のFATの更新ができました。ファイル作成にも影響なさそうです。
Step-5へ続く
|