Skip to content

std.os ​

オペレーティングシステムインターフェースモジュール:ファイルハンドルの読み書き、ディレクトリ操作、環境変数、作業ディレクトリ。

yaoxiang
use std.os

本モジュールのすべての関数はオペレーティングシステムの機能に依存しているため、wasm32 ターゲットではエクスポートされません。

ファイルハンドルモデル ​

ハンドルは参照渡し(#337 修正済み):read / write / seek / tell / flush / close のシグネチャはすべて (file: &File, ...) であるため、ハンドルは繰り返し使用できます:

yaoxiang
f = os.open(p, "w")
os.write(f, "hello world")
os.close(f)

位置決め後の読み書き(seek の存在する理由)も利用可能です:

yaoxiang
r = os.open(p, "r")
os.seek(r, 6)
tail = os.read(r, 5)     // "world"
os.close(r)

修正前のシグネチャには & がなく、ハンドルは値渡し → 線形所有権 → 一度使うと無効となり、 open → write → close は E2014 を報告します。

手動でのハンドル管理を避けたい場合は、ハンドルを開かない便利な関数を使用できます: std.io.read_file / write_file / append_file、または本モジュールの append_file。

open が返すのは Int 型のファイルディスクリプタ(エンジン内部がハンドルテーブルを管理)です。したがってシグネチャ中の File は実質的に Int です。

書き込み後、内容は即座にディスクに反映され、明示的な close は不要です:

yaoxiang
use std.assert
use std.io
use std.os

main: () -> Void = {
    p = "__yx_doc_open.txt"
    n = os.write(os.open(p, "w"), "hello")
    assert(n == 5)
    assert(io.read_file(p) == "hello")
    os.remove(p)
}

open がサポートするモード:

モード意味
r読み取り専用、ファイル必須
w書き込み専用、作成または空にする
a追加、作成または末尾に追加
r+読み書き、ファイル必須
w+読み書き、作成または空にする
a+読み書き、作成または追加

関数一覧 ​

関数シグネチャ
open(path: &String, mode: &String) -> File
close(file: &File) -> Void
read(file: &File, n: Int) -> String
write(file: &File, content: String) -> Int
seek(file: &File, offset: Int) -> Bool
tell(file: &File) -> Int
flush(file: &File) -> Void
mkdir(path: &String) -> Bool
rmdir(path: &String) -> Bool
read_dir(path: &String) -> String
remove(path: &String) -> Bool
exists(path: &String) -> Bool
is_file(path: &String) -> Bool
is_dir(path: &String) -> Bool
copy(src: &String, dst: &String) -> Bool
rename(old: &String, new: &String) -> Bool
get_env(name: &String) -> String
set_env(name: &String, value: &String) -> Void
args() -> String
chdir(path: &String) -> Bool
getcwd() -> String
append_file(path: &String, content: &String) -> Bool

ファイル操作 ​

open ​

yaoxiang
open: (path: &String, mode: &String) -> File

ファイルを開き、ファイルディスクリプタを返します。

  • path —— ファイルパス(読み取り専用借用)
  • mode —— オープンモード、前述の表を参照

戻り値:内部ハンドルテーブルが割り当てる Int ディスクリプタ。このハンドルは一度しか使用できません — 下流のいずれの呼び出しもそれを移動させます(ファイルハンドルモデルを参照)。したがって通常、open は単一の呼び出しにインライン化されます。

エラー:モードが無効、ファイルが存在しない、または権限がない場合、E6007 が発生します。

ハンドルは一度しか使用できない(#337)ため、この戻り値は通常、下流の呼び出しに直接インライン化されます。

yaoxiang
use std.assert
use std.os

main: () -> Void = {
    p = "__yx_doc_open_only.txt"
    f = os.open(p, "w")
    assert(os.exists(p))
    os.remove(p)
}

close ​

yaoxiang
close: (file: &File) -> Void

ファイルハンドルを閉じ、表のエントリを解放します。

ハンドルは一度しか使用できないため、close は「開いた後、他に何もしない」シナリオでのみ意味があります。書き込み内容は write が返る時点で既にディスクに反映されているため、通常は明示的に閉じる必要はありません。

エラー:ディスクリプタが無効(未オープンまたは既に閉じられている)の場合、E6007 が発生します。

yaoxiang
use std.os

main: () -> Void = {
    p = "__yx_doc_close.txt"
    f = os.open(p, "w")
    os.close(f)
    os.remove(p)
}

read ​

yaoxiang
read: (file: &File, n: Int) -> String

現在の読み書き位置から最大 n バイトを読み取ります。

  • file —— ファイルディスクリプタ
  • n —— 読み取り希望バイト数

戻り値:実際に読み取られた内容(n より短い場合があり、ファイル末尾に到達した場合は空文字列)。不正な UTF-8 バイトは置換文字の形式で返され、エラーにはなりません。

エラー:ディスクリプタが無効または読み取りに失敗した場合、E6007 が発生します。

yaoxiang
use std.assert
use std.io
use std.os

main: () -> Void = {
    p = "__yx_doc_read.txt"
    io.write_file(p, "abcdef")

    part = os.read(os.open(p, "r"), 3)
    assert(part == "abc")
    os.remove(p)
}

write ​

yaoxiang
write: (file: &File, content: String) -> Int

現在の読み書き位置に content 全体書き込みます。

  • content —— 値渡し

戻り値:書き込まれたバイト数。

エラー:ディスクリプタが無効または書き込みに失敗した場合、E6007 が発生します。

yaoxiang
use std.assert
use std.os

main: () -> Void = {
    p = "__yx_doc_write.txt"
    n = os.write(os.open(p, "w"), "hello")
    assert(n == 5)
    os.remove(p)
}

seek ​

yaoxiang
seek: (file: &File, offset: Int) -> Bool

読み書き位置を絶対オフセット offset(ファイルの先頭からの相対位置)に移動します。

  • offset —— 目標バイトオフセット、非負であること

戻り値:成功した場合 true。

エラー:ディスクリプタが無効またはオフセットが不正な場合、E6007 が発生します。

yaoxiang
use std.assert
use std.io
use std.os

main: () -> Void = {
    p = "__yx_doc_seek.txt"
    io.write_file(p, "abcdef")

    ok = os.seek(os.open(p, "r"), 2)
    assert(ok)
    os.remove(p)
}

tell ​

yaoxiang
tell: (file: &File) -> Int

現在の読み書き位置のバイトオフセットを返します。

エラー:ディスクリプタが無効な場合、E6007 が発生します。

yaoxiang
use std.assert
use std.os

main: () -> Void = {
    p = "__yx_doc_tell.txt"
    pos = os.tell(os.open(p, "w"))
    assert(pos == 0)
    os.remove(p)
}

flush ​

yaoxiang
flush: (file: &File) -> Void

バッファされた内容をディスクにフラッシュします。

エラー:ディスクリプタが無効またはフラッシュに失敗した場合、E6007 が発生します。

yaoxiang
use std.assert
use std.os

main: () -> Void = {
    p = "__yx_doc_flush.txt"
    os.flush(os.open(p, "w"))
    assert(os.exists(p))
    os.remove(p)
}

ディレクトリ操作 ​

mkdir ​

yaoxiang
mkdir: (path: &String) -> Bool

単一階層のディレクトリを作成します(親ディレクトリを再帰的に作成しません)。

戻り値:成功した場合 true。

エラー:親ディレクトリが存在しない、またはディレクトリが既に存在する場合、E6007 が発生します。

yaoxiang
use std.assert
use std.os

main: () -> Void = {
    d = "__yx_doc_mkdir"
    assert(os.mkdir(d))
    assert(os.is_dir(d))
    os.rmdir(d)
}

rmdir ​

yaoxiang
rmdir: (path: &String) -> Bool

空のディレクトリを削除します。

戻り値:成功した場合 true。

エラー:ディレクトリが存在しない、または空でない場合、E6007 が発生します。

yaoxiang
use std.assert
use std.os

main: () -> Void = {
    d = "__yx_doc_rmdir"
    os.mkdir(d)
    assert(os.rmdir(d))
    assert(!os.exists(d))
}

read_dir ​

yaoxiang
read_dir: (path: &String) -> String

ディレクトリ内のエントリ名を列挙します。

戻り値:エントリ名が \n で連結された単一の文字列(List ではありません)。

エラー:ディレクトリが存在しない、または権限がない場合、E6007 が発生します。

yaoxiang
use std.assert
use std.os
use std.string

main: () -> Void = {
    d = "__yx_doc_read_dir"
    os.mkdir(d)
    names = os.read_dir(d)
    // 空のディレクトリは空文字列を返す
    assert(string.is_empty(names))
    os.rmdir(d)
}

パスとファイルユーティリティ ​

remove ​

yaoxiang
remove: (path: &String) -> Bool

ファイルを削除します。セマンティクスは remove_file と同等です(ディレクトリは削除できません、ディレクトリの削除には rmdir を使用してください)。

戻り値:成功した場合 true。

エラー:ファイルが存在しない、またはパスがディレクトリの場合、E6007 が発生します。

yaoxiang
use std.assert
use std.io
use std.os

main: () -> Void = {
    p = "__yx_doc_remove.txt"
    io.write_file(p, "x")
    assert(os.remove(p))
    assert(!os.exists(p))
}

exists ​

yaoxiang
exists: (path: &String) -> Bool

パスが存在するかどうかを確認します(ファイルまたはディレクトリのいずれか可)。エラーは発生しません。存在しない場合は false を返します。

yaoxiang
use std.assert
use std.os

main: () -> Void = {
    assert(os.exists("."))
    assert(!os.exists("__yx_definitely_missing_path__"))
}

is_file ​

yaoxiang
is_file: (path: &String) -> Bool

パスが通常のファイルかどうかを確認します。ディレクトリは false、存在しない場合は false を返します。

yaoxiang
use std.assert
use std.os

main: () -> Void = {
    assert(!os.is_file("."))
}

is_dir ​

yaoxiang
is_dir: (path: &String) -> Bool

パスがディレクトリかどうかを確認します。ファイルは false、存在しない場合は false を返します。

yaoxiang
use std.assert
use std.os

main: () -> Void = {
    assert(os.is_dir("."))
}

copy ​

yaoxiang
copy: (src: &String, dst: &String) -> Bool

ファイルをコピーします。ターゲットが既に存在する場合は上書きします。

戻り値:成功した場合 true。

エラー:ソースファイルが存在しない、または権限がない場合、E6007 が発生します。

yaoxiang
use std.assert
use std.io
use std.os

main: () -> Void = {
    a = "__yx_doc_copy_a.txt"
    b = "__yx_doc_copy_b.txt"
    io.write_file(a, "data")
    assert(os.copy(a, b))
    assert(io.read_file(b) == "data")
    os.remove(a)
    os.remove(b)
}

rename ​

yaoxiang
rename: (old: &String, new: &String) -> Bool

ファイル名を変更またはファイルを移動します。

戻り値:成功した場合 true。

エラー:ソースファイルが存在しない、またはターゲットが既に存在する場合、E6007 が発生します。

yaoxiang
use std.assert
use std.io
use std.os

main: () -> Void = {
    a = "__yx_doc_rename_a.txt"
    b = "__yx_doc_rename_b.txt"
    io.write_file(a, "data")
    assert(os.rename(a, b))
    assert(os.exists(b))
    os.remove(b)
}

append_file ​

yaoxiang
append_file: (path: &String, content: &String) -> Bool

追加書き込み(ハンドルを開かない便利な関数)。ファイルが存在しない場合は作成されます。

戻り値:成功した場合 true。

エラー:権限がない場合、E6007 が発生します。

これは std.io.append_file の同名同種インターフェースで、両モジュールで提供され、動作も一致しています。

yaoxiang
use std.assert
use std.io
use std.os

main: () -> Void = {
    p = "__yx_doc_os_append.txt"
    io.write_file(p, "a")
    os.append_file(p, "b")
    assert(io.read_file(p) == "ab")
    os.remove(p)
}

環境変数 ​

get_env ​

yaoxiang
get_env: (name: &String) -> String

環境変数を読み取ります。

戻り値:変数の値。変数が存在しない場合は空文字列を返します(エラーは発生しません)。したがって「未設定」と「空文字列に設定」を区別することはできません。

yaoxiang
use std.assert
use std.os
use std.string

main: () -> Void = {
    // PATH は主要プラットフォームでは必ず存在する
    path = os.get_env("PATH")
    assert(string.len(path) > 0)

    // 存在しない変数は空文字列を返す
    assert(string.is_empty(os.get_env("__YX_DEFINITELY_MISSING__")))
}

set_env ​

yaoxiang
set_env: (name: &String, value: &String) -> Void

環境変数を設定します(現在のプロセスに影響します)。

yaoxiang
use std.assert
use std.os

main: () -> Void = {
    os.set_env("__YX_DOC_ENV", "hello")
    assert(os.get_env("__YX_DOC_ENV") == "hello")
}

プロセスと作業ディレクトリ ​

args ​

yaoxiang
args: () -> String

コマンドライン引数を返します。

戻り値:すべての argv が \n で連結された単一の文字列(List ではありません)。最初の項目はプログラム自体のパスです。

yaoxiang
use std.assert
use std.os
use std.string

main: () -> Void = {
    argv = os.args()
    assert(string.len(argv) > 0)
}

chdir ​

yaoxiang
chdir: (path: &String) -> Bool

現在の作業ディレクトリを切り替えます。

戻り値:成功した場合 true。

エラー:ディレクトリが存在しない場合、E6007 が発生します。

yaoxiang
use std.assert
use std.os

main: () -> Void = {
    before = os.getcwd()
    assert(os.chdir(".."))
    assert(os.chdir(before))     // 戻る
    assert(os.getcwd() == before)
}

getcwd ​

yaoxiang
getcwd: () -> String

現在の作業ディレクトリの絶対パスを返します。

エラー:取得できない場合、E6007 が発生します。

yaoxiang
use std.assert
use std.os
use std.string

main: () -> Void = {
    cwd = os.getcwd()
    assert(string.len(cwd) > 0)
}

関連項目 ​