std.stdio
std.c.stdio を拡張する標準入出力関数です。std.stdio を import すると、自動的に std.c.stdio も public に import されます。 Source:std/stdio.d License:
Boost License 1.0. Authors:
Walter Bright, Andrei Alexandrescu
- CのFILE*をカプセル化したものです。
基本的には、DではCの標準ライブラリと同等の関数をほぼそのまま薄いラッパで提供していますが、
FILE* を直接扱うのは色々な面でunsafeでerror-proneです。
この File 型は安全なファイル操作、
自動ファイルクローズなどを簡便に実現しています。
内部的には FILE* はリファレンスカウント方式で管理されています。
従って、それぞれの FILE* に関連づけられた最後の File 変数がなくなるときに、
その FILE*
が自動的にクローズされます。
Example:
// test.d void main(string args[]) { auto f = File("test.txt", "w"); // 書き込み用にオープン f.write("Hello"); if (args.length > 1) { auto g = f; // g と f は同じファイル // ここでのリファレンスカウントは 2 g.write(", ", args[1]); // g がスコープを抜けるので、リファレンスカウントは 1 に減る } f.writeln("!"); // f がスコープを抜けるので、リファレンスカウントは 0 に減る // 内部的なファイルハンドル FILE* が閉じられる }
% rdmd test.d Jimmy % cat test.txt Hello, Jimmy! % _
- this(string name, in char[] stdioOpenmode = "rb");
- ファイルの名前 name とモード (Cの標準関数 fopen のモードと同じ) を受け取ってファイルを開きます。ファイルがオープンできなかった場合、例外を投げます。 File オブジェクトをコピーすると、 同じファイルを参照する2つのFileオブジェクトができます。 デストラクタは、同じファイルを参照する File が1つもなくなった時点でファイルを閉じます。
- ファイルハンドルを他のファイルハンドルへ代入します。代入先が元々関連づけらられていたファイルハンドルは detach され、 新しいファイルに attach されます。
- まず detach を呼び出し(失敗時には例外が飛びます)、次に ファイル name をモード stdioOpenmode で開きます。 モードの値は C の標準ライブラリの fopen 関数と同じ意味です。エラー時には例外を投げます。
- ファイルがオープン済みならば true を返します。
- ファイルが終端に達していれば true を返します(feof 参照)。 ファイルが未オープンの場合は例外が発生します。
- (もしあれば) ファイル名を返します。
- ファイルが未オープンならば、false を返します。オープン済みならば、 ferror の呼び出し結果を返します。
- 管理しているファイルとの関連づけを切り離します。このFileオブジェクトが対象の唯一の所有者であった場合は、close を呼び出し、失敗すると例外を投げます。
- ファイルが未オープンならば、無条件で成功します。オープン済みならば、 ファイルを閉じます (fclose を呼び出します)。 エラー時には例外を投げます。例外が発生した場合であっても、closeの呼び出し後には File オブジェクトは空状態になっています。この関数は常にファイルを閉じるという意味で detach と異なっています。 つまり、同じファイルハンドルを参照している File オブジェクトは、以降close済みのハンドルを持つことになります。
- ファイルが未オープンならば、無条件で成功します。オープン済みならば、 clearerr を呼び出します。
- ファイルが未オープンならば、例外を投げます。オープン済みならば、fflush を呼び出します。エラー時には例外を投げます。
- ファイルが未オープンならば、例外を投げます。オープン済みならば、fread を呼び出します。エラー時には例外を投げます。 rawRead always read in binary mode on Windows.
- ファイルが未オープンならば、例外を投げます。オープン済みならば、fwrite を呼び出します。エラー時には例外を投げます。 rawWrite always write in binary mode on Windows.
- ファイルが未オープンならば、例外を投げます。オープン済みならば、fseek を呼び出します。エラー時には例外を投げます。
- ファイルが未オープンならば、例外を投げます。オープン済みならば、ftell を呼び出します。エラー時には例外を投げます。
- ファイルが未オープンならば、例外を投げます。オープン済みならば、rewind を呼び出します。エラー時には例外を投げます。
- ファイルが未オープンならば、例外を投げます。オープン済みならば、 setvbuf を呼び出します。
- ファイルが未オープンならば、例外を投げます。オープン済みならば、 setvbuf を呼び出します。
- ファイルが未オープンならば、例外を投げます。オープン済みならば、 引数を文字列化してファイルに書き込みます。
- ファイルが未オープンならば、例外を投げます。オープン済みならば、 引数を文字列化してファイルに書き込み、続けて改行を書き込みます。
- ファイルが未オープンならば、例外を投げます。オープン済みならば、 引数が第一引数の書式指定に従って文字列化され、 ファイルに書き込まれます。
- writefと同様ですが、最後に改行が追加されます。
- ストリームから buf[] へ、
行終端文字も含めて一行読み込みます。
Parameters:
buf 結果の行データを格納するバッファです。 必要な場合はリサイズされます。
EOF時には0、それ以外は読み込まれた文字の数 Throws:
エラー時に StdioException Example:
// stdin を読んで stdout に書く import std.stdio; int main() { char[] buf; while (stdin.readln(buf)) write(buf); return 0; }
stdin.readln() よりも stdin.readln(buf) の方が、(可能な限り) buf のメモリを再利用するので高速です。buf = readln() の方は、 毎回新しくメモリ割り当てが行われます。 - tmpfile を呼び出して一時ファイルを作成します。
- 既存の FILE* をラップする unsafe 関数です。作られた File オブジェクトは自動でファイルを閉じることはありません。
- このオブジェクトに対応する FILE* を返します。
- このオブジェクトに対応するファイルナンバーを返します。
- 一度に一行ずつファイルを読み込むレンジオブジェクトです
- このファイルに対する LinesReader を返す便利関数です。
- チャンク分けしてデータを読み込むレンジです。
- レンジの基本操作
- foreach によって、ファイルをチャンクに分割して読み込みます。
Example:
void main() { foreach (ubyte[] buffer; stdin.byChunk(4096)) { ... use buffer ... } }
buffer の中身は呼び出しのたびに再利用されます。 上の例では、最後の1回を除き buffer.length は常に4096です。 最後の1回は buffer.length は4096より小さい可能性があります。 (ただし常に0よりは大きいです) I/O エラーが起きると、StdioException 例外を投げます。 - ファイルをロックして高速な書き込みを行うレンジオブジェクト。
- レンジのインターフェイス関数の実装
- 便利関数
- ファイルのサイズを取得します。サイズ不明の場合は ulong.max を返しますが、実際にエラーが起きるとやはり例外を投げます。
- args 内のそれぞれの引数を
(to!(string)(arg) と同様に文字列化して)、
args[0] へと書き込みます。
引数無しでの呼び出しはコンパイルエラーです。
Throws:
I/O エラーが起きると、StdioException 例外を投げます。 - write(args, '\n') と同じ。writeln を引数無しで呼び出すことは可能で、 その場合は単に改行文字が出力されます。
- 先頭の引数 args[0] が FILE* なら、
args[1] を 書式指定
と解釈して残りの args[2..$] を文字列化し、結果の文字列を args[0] に書き込みます。
arg[0] が FILE* でないときは、
writef(stdout, args) と同じ意味になります。
IMPORTANT:
D 2.006 から動作が変わりました。前のバージョンと違って writef (writefln も同様) は、先頭の文字列に含まれている書式指定のみを解釈します。 この仕様変更の理由は、古い仕様では、 パーセント記号が入る可能性のある文字列変数を単純に表示しようとするのが 無駄に大変になってしまっていたのでこれを避けるためです。 また、2.006 では POSIX の引数指定構文(positional parameter)がサポートされました。 Example:
writef("Date: %2$s %1$s", "October", 5); // "Date: 5 October"
引数指定構文とそうでないスタイルは、同じ書式指定のなかで混ぜて使うことができます。 (POSIX ではこの場合の挙動は未定義です。) 引数位置指定のない引数に対しては、内部のカウンタは、 最後に使用された引数指定の次の引数を指すようになっています。 2.008からの動作: rawフォーマット指定。"%r" を指定すると、writef は引数のバイナリ表現を そのまま出力します。"%-r" は数値をリトルエンディアンで、 "%+r" はビッグエンディアンで、"%r" はプラットフォームの標準のエンディアンで出力します。 - writef(args, '\n') と同じ
- 書式指定に従い標準入力から1行読み込みます。
- ストリーム fp から一行読み込みます。
Returns:
ファイル終端ならば null、それ以外では 行末文字 terminator を含めて1行 fp から読み込んで返します。 Parameters:Throws:
エラー時に StdioException Example:
stdin を読んで stdout に書き込みます。import std.stdio; int main() { char[] buf; while ((buf = readln()) != null) write(buf); return 0; }
- foreach によって、ファイルを行ごとに分割して読み込みます。
Example:
void main() { foreach (string line; lines(stdin)) { ... use line ... } }
行区切り文字 (デフォルトは '\n') も文字列に含まれます (ファイルの最後の行が 改行を含んでいない場合をのぞく)。 line として使える型はいくつかあり、それぞれで lines の動作は以下のように変わります:- line の型が string、 wstring、dstring の場合、指定された型の文字列が 毎回割り当てられます。
- line の型が char[]、wchar[]、dchar[] の場合、line の内容は 読み込み毎に再利用 (上書き) されます。
- line の型が invariant(ubyte)[] の場合、動作は場合 (1) と似ていますが、 入力に対するUTFのチェックが行われなくなります。
- line の型が ubyte[] の場合、動作は場合 (2) と似ていますが、 入力に対するUTFのチェックが行われなくなります。
foreach (ulong i, string line; lines(stdin)) { ... use line ... }
I/O エラーが起きると、 StdioException 例外を投げます。 - foreach によって、ファイルをチャンクに分割して読み込みます。
Example:
void main() { foreach (ubyte[] buffer; chunks(stdin, 4096)) { ... use buffer ... } }
buffer の中身は呼び出しのたびに再利用されます。 上の例では、最後の1回を除き buffer.length は常に4096です。 最後の1回は buffer.length は4096より小さい可能性があります。 (ただし常に0よりは大きいです) I/O エラーが起きると、 StdioException 例外を投げます。 - I/O エラーが起きたときに発生する例外です
- OSのエラーコード
- this(string message, uint e = module stdio.getErrno);
- メッセージとエラーコードを指定して例外オブジェクトを作成
- StdioException を throw するための便利関数