Kinx ライブラリ - File/Directory

# ライブラリ（File/Directory）

## はじめに

「見た目は JavaScript、頭脳(中身)は Ruby、（安定感は AC/DC）」でお届けしているスクリプト言語 Kinx。[前回](https://qiita.com/Kray-G/items/4c6011279d0bd3036da8)の記事で **プレビュー・リリースしたぜ** と勇み足ぎみに突っ走ったが、マニュアルが整っていないので、やはりなかなか使いづらいに違いない。現時点で参考になるのは以下しかないし、英語なので。

*   [Quick Reference Guide](https://github.com/Kray-G/kinx/blob/master/doc/QuickReference.md)
*	[Kinx Specification](https://github.com/Kray-G/kinx/blob/master/doc/spec/README.md)
*	[初回紹介記事](https://qiita.com/Kray-G/items/ca08b6fb40d15dd0ec76) からの各種リンク
	*   一応、ここは日本語。

そこでだ、若旦那。

少しだけマニュアル代わりになるように、簡易説明をここに記すことにしましたよ。今回は File と Directory。一番実用的な感じがしたので。

> 重要:  
> v0.1.0 ではファイル系のインタフェースが不完全だったので、急遽 v0.2.0 を用意しました。下記の内容は v0.2.0 のものです。v0.1.0 では動作しないものが一部あります。
> また、標準入力をサポートしました。リリース内容は下記を参照してください。
> * [リリース・リスト](https://github.com/Kray-G/kinx/releases)

## ライブラリ

### File クラス

File クラスはその名の通りファイルの読み書きをするクラスで、静的メソッドを持つ。また、`new File(filename, attr)` として個別のファイル・インスタンスを作成することもできる。

#### 静的メソッド

File クラスの静的メソッドは、以下の通り。

|            メソッド             |                  内容                  |             復帰値(型)             |      引数       |                意味                |
| ------------------------------- | -------------------------------------- | ---------------------------------- | --------------- | ---------------------------------- |
| `File.load(path)`               | ファイル内容をテキスト形式で一括読込み | String                             | path: String    | 中身を読み込むファイルパス         |
| `File.mkdir(path)`              | ディレクトリの作成                     | 1: 成功                            | path: String    | 作成するディレクトリ・パス         |
| `File.rename(oldname, newname)` | ファイルパスの変更                     | 1: 成功                            | oldname: String | 変更前のファイルパス               |
|                                 |                                        |                                    | newname: String | 変更後のファイルパス               |
| `File.unlink(path)`             | ファイルの削除                         | 1: 成功                            | path: String    | 削除するファイルパス               |
| `File.exists(path)`             | ファイルの存在確認                     | 1: 存在する                        | path: String    | 確認するファイルパス               |
| `File.isDirectory(path)`        | ディレクトリ名かどうかの確認           | 1: ディレクトリである              | path: String    | 確認するファイルパス               |
| `File.isSymlink(path)`          | シンボリックリンクかどうかの確認       | 1: シンボリックリンクである        | path: String    | 確認するファイルパス               |
| `File.filesize(path)`           | ファイルサイズの取得                   | Integer                            | path: String    | 確認するファイルパス               |
| `File.filedate(path)`           | ファイル日付の取得                     | `{ modified, accessed, creation }` | path: String    | 確認するファイルパス               |
| `File.setFiledate(path, obj)`   | ファイル日付の設定                     |                                    | path: String    | 確認するファイルパス               |
|                                 |                                        |                                    | obj: Object     | `{ modified, accessed, creation }` |

#### File インスタンス

File インスタンスは `new` で作る。サンプルは以下の通り。

```javascript
var f = new File(filename, attr);
```

パラメータは以下の 2 つ。

| パラメータ |    取りうる値    |      意味      |
| ---------- | ---------------- | -------------- |
| filename   | 文字列           | ファイル名     |
| attr       | 以下の値の論理和 | オープン属性   |
|            | `File.READ`      | 読込可能       |
|            | `File.WRITE`     | 書込可能       |
|            | `File.APPEND`    | 追記モード     |
|            | `File.TEXT`      | テキストモード |
|            | `File.BINARY`    | バイナリモード |

*   オープン属性は以下のような感じで指定する。
    *   `File.READ|File.APPEND`... 追記モードで読み書き可能
    *   `File.READ|File.WRITE` ... 新規作成モードで読み書き可能
    *   `File.READ|File.TEXT`  ... テキストモードで読み込み専用

File インスタンスのメソッドは以下の通り。すみません、`peek`、`getch`、`putch` は v0.1.0 に含まれていません。。。

|       メソッド       |             内容             |         復帰値(型)         |    引数     |           意味           |
| -------------------- | ---------------------------- | -------------------------- | ----------- | ------------------------ |
| `f.load()`           | ファイルの中身を一括読み込み | String                     |             |                          |
| `f.close()`          | ファイルをクローズ           |                            |             |                          |
| `f.readLine()`       | 一行読み込み                 | String, 0: EOF             |             |                          |
| `f.peek(ms)`         | 入力があるか確認             | 1: 存在する、0: 存在しない | ms: Integer | タイムアウト（ミリ秒）   |
| `f.getch()`          | 1 文字入力                   | Integer (取得文字コード)   |             |                          |
| `f.putch(ch)`        | 1 文字出力                   |                            | ch: Integer | 出力文字コード           |
| `f.print(...args)`   | 改行文字なしで出力           | 出力文字数: Integer        | ...args     | 表示する要素（可変引数） |
| `f.println(...args)` | 改行文字付きで出力           | 出力文字数: Integer        | ...args     | 表示する要素（可変引数） |

#### File.open

個別に `new` した場合は `close` しなければならない（GC されたら勝手にクローズ自体はされる）が、スコープを決めて自動的にクローズさせたい場合は `File.open` を使うのがオススメ。スコープを抜けるとその場で自動的にクローズされる。こんな感じ。

```javascript
File.open("README.md", File.READ, &(f) => {
    var l, n = 0;
    while ((l = f.readLine()).isString) {
        System.println("%4d: %s" % (++n) % l);
    }
});
```

`File.open` の内容としては、意味的には次のと概ね同等。

```javascript
function FileOpen(filename, attr, func) {
    var f = new File(filename, attr);
    try {
        return func(f);
    } finally {
        f.close();
    }
}
```

### Directory

ディレクトリをトラバースするために使う。サブディレクトリを見つけた時に再帰的に潜っていく場合は `recursiveWalk`、潜っていかない場合は `walk` を使う。

#### Directory.walk

Kinx のリポジトリ・フォルダで以下を実行してみるとなんとなくわかるかも（"src" ディレクトリがあるので動作する、という意味。存在するディレクトリ名にすればどこでも OK）。

```javascript
Directory.walk("src", &(name) => {
    System.println(name);
});
```

#### Directory.recursiveWalk

次のように実行すると違いがわかるはず（"src" 配下にサブディレクトリがある前提）。

```javascript
Directory.recursiveWalk("src", &(name) => {
    System.println(name);
});
```

## おわりに

先日、昔のツェッペリンのインタビューを読んでみて、新しい何か、自分たちがやりたい何か、をガレージ・レベルからスタートさせてやっていく、ってのは改めて **ロックだねえ**、と感慨に耽っていました。ビッグになったロックスターたちも、最初は **こういうのやりたいんだよ** とガレージやクラブからスタートさせてる訳です。夢と希望を忍ばせて。

今あるものに満足せずに、また、今現在提供されているものに満足行かないようなら、文句を言うのではなく自分の手で実現させてしまうのが良いよね。そのアティテュードこそがまさに **ロックンロール**。

まだまだ転がり続けようぜ。

で、最後はいつものおねだりの時間です。

* 最初の動機は [スクリプト言語 KINX（ご紹介）](https://qiita.com/Kray-G/items/ca08b6fb40d15dd0ec76) を参照してください（もし宜しければ**「~~いいね~~ LGTM」**ボタンをポチっと）。
* リポジトリは [ここ（https://github.com/Kray-G/kinx）](https://github.com/Kray-G/kinx) です。こちらももし宜しければ★をポチっと。