2023年03月26日くいなちゃん


プログラミング言語Kuin」の実行環境がexe用の逆引き辞典7、ファイルを読み書きする方法についてです。

ファイルやディレクトリを操作する

テキスト、バイナリファイルを読み書きする

XMLファイルを読み書きする

目次

1ファイルやディレクトリを操作する

Kuinではファイルパスの区切り文字には「\」は使わず「/」を使い、ディレクトリパスを表すときには終端に「/」を付けます。 つまり「"a\b\c"」とは書かずに、「"a/b/c/"」と書きます。
Kuinの標準ライブラリの関数の引数は、編集対象を先に指定する順番で統一しています。 このため、コピー関数の引数は「コピー先, コピー元」の順になりますのでご注意ください。

1.1ファイルやディレクトリをコピーする



ファイルをコピーするには「file@copyFile(コピー先パス, コピー元パス)」とし、ディレクトリをコピーするには「file@copyDir(コピー先パス, コピー元パス)」とします(図1-1)。
  1. func main()
  2.   var b: bool
  3.   do b :: file@copyFile("dst_dir/dst_file.txt", "src_dir/src_file.txt")
  4.   do b :: file@copyDir("dst_dir/", "src_dir/")
  5. end func
図1-1: ファイルやディレクトリのコピー
これらの関数は、コピーが成功すると「true」、失敗すると「false」を返します。 また「file@copyDir」関数は中身のサブディレクトリやファイルも一緒にコピーされます。

1.2ファイルやディレクトリを移動する



(この記事は執筆中です!)

1.3ファイルやディレクトリを削除する



ファイルを削除するには「file@delFile(パス)」とし、ディレクトリを削除するには「file@delDir(パス)」とします(図1-2)。
  1. func main()
  2.   var b: bool
  3.   do b :: file@delFile("dst_dir/dst_file.txt")
  4.   do b :: file@delDir("dst_dir/")
  5. end func
図1-2: ファイルやディレクトリの削除
これらの関数は、削除が成功すると「true」、失敗すると「false」を返します。 削除対象が存在しない場合には、何もせずに「true」が返ります。
また「file@delDir」関数は中身のサブディレクトリやファイルも一緒に削除されます。

1.4ディレクトリを作成する



ディレクトリを作成するには「file@makeDir(パス)」とします(図1-3)。
  1. func main()
  2.   var b: bool :: file@makeDir("dst_dir/")
  3. end func
図1-3: ディレクトリの作成
「a/b/c/」としたとき、「b」と「c」のディレクトリが存在しない場合には「b」も「c」も作成されます。
またディレクトリの中身は空になります。 「a/b/c/」としたとき、「b」と「c」のディレクトリが既に存在していた場合、「b」の中身はそのままですが、「c」の中身のサブディレクトリやファイルはすべて削除されます。

1.5ファイルやディレクトリの存在を確認する



ファイルやディレクトリが存在しているかどうかを取得するには「file@exist(パス)」とします(図1-4)。
  1. func main()
  2.   var b: bool
  3.   do b :: file@exist("dst_dir/dst_file.txt")
  4.   do b :: file@exist("dst_dir/")
  5. end func
図1-4: ファイルやディレクトリの存在の取得
存在していれば「true」、していなければ「false」が返ります。

1.6ファイルのサイズを取得する



ファイルのサイズを取得するには「file@fileSize(パス)」とします(図1-5)。
  1. func main()
  2.   var size: int :: file@fileSize("dst_dir/dst_file.txt")
  3. end func
図1-5: ファイルサイズの取得
戻り値の単位はbyteです。

1.7ディレクトリ内のファイルを列挙する



(この記事は執筆中です!)

1.8パスの一部を抜き出す



ファイルパスから、ディレクトリ部分を抜き出すには「file@dir」を使い、拡張子を除いた部分を抜き出すには「file@delExt」を使い、拡張子を抜き出すには「file@ext」を使い、ファイル名を抜き出すには「file@fileName」を使います(図1-6)。
  1. func main()
  2.   var dst: []char :: "dst_dir/dst_file.txt"
  3.   var s: []char
  4.   do s :: file@dir(s) {"dst_dir/"}
  5.   do s :: file@delExt(s) {"dst_dir/dst_file"}
  6.   do s :: file@ext(s) {"txt"}
  7.   do s :: file@fileName(s) {"dst_file.txt"}
  8. end func
図1-6: パスの整形

1.9自身の実行ファイルのディレクトリパスを取得する



自身の実行ファイルファイル(.exe)が存在するディレクトリパスを取得するには「wnd@exeDir()」とします(図1-7)。
  1. func main()
  2.   var path: []char :: wnd@exeDir()
  3. end func
図1-7: 実行ファイルのディレクトリの取得

1.10特殊なディレクトリのパスを取得する



デスクトップなどの特殊なディレクトリのパスを取得するには「wnd@sysDir(特殊なディレクトリの種類)」とします(図1-8)。
  1. func main()
  2.   var s: []char
  3.   do s :: wnd@sysDir(%appData) {アプリケーションデータ}
  4.   do s :: wnd@sysDir(%desktop) {デスクトップ}
  5.   do s :: wnd@sysDir(%fonts) {フォント}
  6.   do s :: wnd@sysDir(%programFiles) {ProgramFiles}
  7.   do s :: wnd@sysDir(%system32) {System32}
  8.   do s :: wnd@sysDir(%windows) {Windowsディレクトリ}
  9. end func
図1-8: 特殊なディレクトリパスの取得

2テキスト、バイナリファイルを読み書きする

2.1テキストファイルを読み込む



テキストファイルを読み込むには、「file@makeReader(パス)」でファイルを開いてから、各種メソッドでデータを読み込み、最後にfinメソッドでファイルを閉じます(図2-1)。
  1. func main()
  2.   var handle: file@Reader :: file@makeReader("text_file.txt")
  3.   do handle.delimiter(['\n', ',']) {区切り文字の設定}
  4.  
  5.   var s: []char :: handle.readStr() {文字列を読み込む}
  6.   var i: int :: handle.readInt() {整数を読み込む}
  7.   var f: float :: handle.readFloat() {小数を読み込む}
  8.   var c: char :: handle.readChar() {文字を読み込む}
  9.  
  10.   var c2: char :: handle.readLetter() {区切り文字を無視して1文字読み込み}
  11.   var s2: []char :: handle.readLine() {区切り文字を無視して1行読み込み}
  12.   do handle.fin()
  13. end func
図2-1: テキストファイルの読み込み
file@Readerクラスの「delimiter」メソッドで区切り文字の配列を登録すると、「readStr」「readInt」「readFloat」「readChar」メソッドはそれらの文字が出てくるまでを読み込んで返します。
読み込んだデータが想定している型と一致しない場合には例外が発生しますので、どの型になるかが判らないときには「readStr」で読み込んで「toInt」「toFloat」メソッドなどで変換してください。
「readLetter」「readLine」メソッドは区切り文字を無視して読み込みます。

2.2バイナリファイルを読み込む



バイナリファイルを読み込むには、テキストファイルと同様「file@makeReader(パス)」でファイルを開いてから、readメソッドでデータを読み込み、最後にfinメソッドでファイルを閉じます(図2-2)。
  1. func main()
  2.   var handle: file@Reader :: file@makeReader("binary_file.bin")
  3.   var size: int :: handle.fileSize() {ファイルサイズの取得}
  4.   var bin: []bit8 :: handle.read(size) {指定したbyte分だけバイナリを取得}
  5.   do handle.fin()
  6. end func
図2-2: バイナリファイルの読み込み

2.3テキスト、バイナリファイルの終端を判定する



テキストファイルやバイナリファイルの読み込み時に終端を判定するには、file@Readerクラスの「term」メソッドを使います(図2-3)。
  1. func main()
  2.   var handle: file@Reader :: file@makeReader("text_file.txt")
  3.  
  4.   while(!handle.term()) {終端でなければ処理を繰り返す}
  5.     var s2: []char :: handle.readLine() {1行読み込み}
  6.   end while
  7.  
  8.   do handle.fin()
  9. end func
図2-3: テキスト、バイナリファイルの終端判定
termメソッドは、もう読み込めるデータがなければtrue、まだ残っていればfalseを返します。

2.4テキストファイルを書き込む



テキストファイルを書き込むには、「file@makeWriter(パス, 新規ならfalse、追記ならtrue)」でファイルを開いてから、各種メソッドでデータを書き込み、最後にfinメソッドでファイルを閉じます(図2-4)。
  1. func main()
  2.   var handle: file@Writer :: file@makeWriter("text_file.txt", false)
  3.   do handle.writeStr("ABC") {文字列を書き込む}
  4.   do handle.writeInt(1234) {整数を書き込む}
  5.   do handle.writeFloat(0.123) {小数を書き込む}
  6.   do handle.writeChar('X') {文字を書き込む}
  7.   do handle.fin()
  8. end func
図2-4: テキストファイルの書き込み
既にファイルが存在していた場合、file@makeWriterの第2引数にfalseを指定すると削除して新規ファイルとして書き込まれ、trueを指定すると末尾に追記していきます。

2.5バイナリファイルを書き込む



バイナリファイルを書き込むには、テキストファイルと同様「file@makeWriter(パス, 新規ならfalse、追記ならtrue)」でファイルを開いてから、writeメソッドでデータを書き込み、最後にfinメソッドでファイルを閉じます(図2-5)。
  1. func main()
  2.   var handle: file@Writer :: file@makeWriter("binary_file.bin", false)
  3.   do handle.write([0x12b8, 0x34b8, 0x56b8, 0x78b8])
  4.   do handle.fin()
  5. end func
図2-5: バイナリファイルの書き込み

2.6テキスト、バイナリファイルのアクセス位置を操作する



テキストファイルやバイナリファイルの読み込み位置や書き込み位置を操作するには、file@Readerやfile@Writerクラスの「getPos」「setPos」メソッドを使います(図2-6)。
  1. func main()
  2.   var handle: file@Reader :: file@makeReader("binary_file.bin")
  3.   var pos: int :: handle.getPos() {アクセス位置の取得}
  4.   do handle.setPos(%head, pos) {アクセス位置の設定}
  5.   do handle.fin()
  6. end func
図2-6: テキスト、バイナリファイルのアクセス位置の操作
setPosメソッドの第1引数には、どの位置を基準にするかを指定します。 ファイルの先頭を基準に相対位置で指定する場合は「%head」、現在のアクセス位置を基準にする場合は「%cur」、ファイルの末尾を1byte超えた地点を基準にする場合は「%tail」を指定します。

3XMLファイルを読み書きする

(この記事は執筆中です!)
1679823717jaf