| Category | Symbols |
|---|---|
| File handles | _popen File isFileHandle openNetwork stderr stdin stdout |
| Reading | chunks lines readf readfln readln |
| Writing | toFile write writef writefln writeln |
| Misc | KeepTerminator LockType StdioException |
Sourcestd/stdio.d
KeepTerminator = std.typecons.Flag!"keepTerminator".Flag;KeepTerminator is set toKeepTerminator.yes, then the delimiteris included in the strings returned.File;File type ensures safe manipulation, automaticfile closing, and a lot of convenience.File variable bound to agivenFILE* goes out of scope, the underlyingFILE* isautomatically closed.Example
// test.dimport std.stdio;void main(string[] args){auto f =File("test.txt","w");// open for writing f.write("Hello");if (args.length > 1) {auto g = f;// now g and f write to the same file// internal reference count is 2 g.write(", ", args[1]);// g exits scope, reference count decreases to 1 } f.writeln("!");// f exits scope, reference count falls to zero,// underlying `FILE*` is closed.}
% rdmd test.d Jimmy% cat test.txtHello, Jimmy!% _
name, scope const(char)[]stdioOpenmode = "rb");name)name, R2mode)stringname | range or string representing the file name |
const(char)[]stdioOpenmode | range or string represting the open mode (with the same semantics as in the C standard libraryfopen function) |
opAssign(Filerhs) return;open(stringname, scope const(char)[]stdioOpenmode = "rb");name with modestdioOpenmode. The mode has thesame semantics as in the C standard libraryfopen function.reopen(stringname, scope const(char)[]stdioOpenmode = "rb");name isnull, the mode of the currently openfile is changed; otherwise, a new file is opened, reusing the CFILE*. The function has the same semantics as in the C standardlibraryfreopen function.NoteCallingreopen with anullname is not implementedin all C runtimes.
popen(stringcommand, scope const(char)[]stdioOpenmode = "r");fdopen(intfd, scope const(char)[]stdioOpenmode = "rb");intfd | File descriptor to associate with thisFile. |
const(char)[]stdioOpenmode | Mode to associate with this File. The mode has the same semantics as in the POSIX library functionfdopen and must be compatible withfd. |
windowsHandleOpen(HANDLEhandle, scope const(char)[]stdioOpenmode);isOpen() const;eof() const;name() const return;error() const;detach();close();clearerr();flush();sync();rawRead(T)(T[]buffer);buffer containing the data that was actually read.This will be shorter thanbuffer if EOF was reached before the buffercould be filled. If the buffer is empty, it will be returned.rawRead always reads in binary mode on Windows.staticimport std.file;auto testFile = std.file.deleteme();std.file.write(testFile,"\r\n\n\r\n");scope(exit) std.file.remove(testFile);auto f = File(testFile,"r");auto buf = f.rawRead(newchar[5]);f.close();writeln(buf);// "\r\n\n\r\n"
rawWrite(T)(in T[]buffer);rawWrite always writes in binary mode on Windows.staticimport std.file;auto testFile = std.file.deleteme();auto f = File(testFile,"w");scope(exit) std.file.remove(testFile);f.rawWrite("\r\n\n\r\n");f.close();writeln(std.file.read(testFile));// "\r\n\n\r\n"
seek(longoffset, intorigin = SEEK_SET);tell() const;import std.conv : text;staticimport std.file;auto testFile = std.file.deleteme();std.file.write(testFile,"abcdefghijklmnopqrstuvwqxyz");scope(exit) { std.file.remove(testFile); }auto f = File(testFile);auto a =newubyte[4];f.rawRead(a);writeln(f.tell);// 4
rewind();setvbuf(size_tsize, intmode = _IOFBF);setvbuf fails.setvbuf(void[]buf, intmode = _IOFBF);setvbuf fails.lock(LockTypelockType = LockType.readWrite, ulongstart = 0, ulonglength = 0);start andlength are zero, the entire file is locked.lock andtryLock have the following properties:tryLock(LockTypelockType = LockType.readWrite, ulongstart = 0, ulonglength = 0);start andlength are zero, the entire file is locked.unlock(ulongstart = 0, ulonglength = 0);write(S...)(Sargs);writeln(S...)(Sargs);writef(alias fmt, A...)(Aargs)writef(Char, A...)(in Char[]fmt, Aargs);Char[]fmt | Theformat string.When passed as a compile-time argument, the string will be statically checkedagainst the argument types passed. |
Aargs | Items to write. |
writefln(alias fmt, A...)(Aargs)writefln(Char, A...)(in Char[]fmt, Aargs);fmt,args, '\n').readln(S = string)(dcharterminator = '\n')readln(buf) version, which may offerbetter performance as it can reuse its read buffer.| S | Template parameter; the type of the allocated buffer, and the type returned. Defaults tostring. |
dcharterminator | Line terminator (by default,'\n'). |
NoteString terminators are not supported due to ambiguity with readln(buf) below.
Example
// Reads `stdin` and writes it to `stdout`.import std.stdio;void main(){ string line;while ((line = stdin.readln()) !isnull) write(line);}
readln(C)(ref C[]buf, dcharterminator = '\n')readln(C, R)(ref C[]buf, Rterminator)terminator.front == (dchar).init)));buf[], includingterminating character.C[]buf | Buffer used to store the resulting line data. buf isenlarged if necessary, then set to the slice exactly containing the line. |
dcharterminator | Line terminator (by default,'\n'). Usestd.ascii.newline for portability (unless the file was opened intext mode). |
buf.length.Example
// Read lines from `stdin` into a string// Ignore lines starting with '#'// Write the string to `stdout`import std.stdio;void main(){ string output;char[]buf;while (stdin.readln(buf)) {if (buf[0] == '#')continue; output ~=buf; } write(output);}This method can be more efficient than the one in the previous examplebecausestdin.
readln(buf) reuses (if possible) memory allocatedforbuf, whereasline = stdin.readln() makes a new memory allocationfor every line.For even better performance you can helpreadln by passing in alarge buffer to avoid memory reallocations. This can be done by reusing thelargest buffer returned byreadln:Example
// Read lines from `stdin` and count wordsimport std.array, std.stdio;void main(){char[]buf; size_t words = 0;while (!stdin.eof) {char[] line =buf; stdin.readln(line);if (line.length >buf.length)buf = line; words += line.split.length; } writeln(words);}This is actually whatbyLine does internally, so its usageis recommended if you want to process a complete file.
readf(alias format, Data...)(auto ref Datadata)readf(Data...)(scope const(char)[]format, auto ref Datadata);const(char)[]format | Theformat string. When passed as a compile-time argument, the string will be statically checked against the argument types passed. |
Datadata | Items to be read. |
Example
// test.dvoid main(){import std.stdio;auto f = File("input");foreach (_; 0 .. 3) {int a; f.readf!" %d"(a); writeln(++a); }}
% echo "1 2 3" > input% rdmd test.d234
staticimport std.file;auto deleteme = std.file.deleteme();std.file.write(deleteme,"hello\nworld\ntrue\nfalse\n");scope(exit) std.file.remove(deleteme);string s;auto f = File(deleteme);f.readf!"%s\n"(s);writeln(s);// "hello"f.readf("%s\n", s);writeln(s);// "world"bool b1, b2;f.readf("%s\n%s\n", b1, b2);assert(b1 ==true && b2 ==false);
readfln(alias format, Data...)(auto ref Datadata)readfln(Data...)(scope const(char)[]format, auto ref Datadata);const(char)[]format | Theformat string. When passed as a compile-time argument, the string will be statically checked against the argument types passed. |
Datadata | Items to be read. |
Example
// sum_rows.dvoid main(){import std.stdio;auto f = File("input");int a, b, c;while (f.readfln("%d %d %d", a, b, c) == 3) { writeln(a + b + c); }}
% cat << EOF > input1 2 34 5 67 8 9EOF% rdmd sum_rows.d61524
tmpfile();wrapFile(FILE*f);getFP();fileno() const;windowsHandle();byLine(Terminator = char, Char = char)(KeepTerminatorkeepTerminator = No.keepTerminator, Terminatorterminator = '\n')byLine(Terminator, Char = char)(KeepTerminatorkeepTerminator, Terminatorterminator)NoteEachfront will not persist afterpopFront is called, so the caller must copy its contents (e.g. bycallingto!string) when retention is needed. If the caller needsto retain a copy of every line, use thebyLineCopy functioninstead.
| Char | Character type for each line, defaulting tochar. |
KeepTerminatorkeepTerminator | UseYes.keepTerminator to include theterminator at the end of each line. |
Terminatorterminator | Line separator ('\n' by default). Usestd.ascii.newline for portability (unless the file was opened intext mode). |
Example
import std.algorithm, std.stdio, std.string;// Count words in a file using ranges.void main(){auto file = File("file.txt");// Open for readingconst wordCount = file.byLine()// Read lines .map!split// Split into words .map!(a => a.length)// Count words per line .sum();// Total word count writeln(wordCount);}
Example
import std.range, std.stdio;// Read lines using foreach.void main(){auto file = File("file.txt");// Open for readingauto range = file.byLine();// Print first three linesforeach (line; range.take(3)) writeln(line);// Print remaining lines beginning with '#'foreach (line; range) {if (!line.empty && line[0] == '#') writeln(line); }}Notice that neither example accesses the line data returned byfront after the correspondingpopFront call is made (becausethe contents may well have changed).
Windows specific Example:import std.stdio;version (Windows)void main(){foreach (line; File("file.txt").byLine(No.keepTerminator, "\r\n")){writeln("|"~line~"|");if (line == "HelloWorld") writeln("^This Line is here.");}}
byLineCopy(Terminator = char, Char = immutable(char))(KeepTerminatorkeepTerminator = No.keepTerminator, Terminatorterminator = '\n')byLineCopy(Terminator, Char = immutable(char))(KeepTerminatorkeepTerminator, Terminatorterminator)NoteDue to caching byLineCopy can be more memory-efficient thanFile.byLine.map!idup.
The element type for the range will beChar[]. Rangeprimitives may throwStdioException on I/O error.| Char | Character type for each line, defaulting toimmutable char. |
KeepTerminatorkeepTerminator | UseYes.keepTerminator to include theterminator at the end of each line. |
Terminatorterminator | Line separator ('\n' by default). Usestd.ascii.newline for portability (unless the file was opened intext mode). |
Example
import std.algorithm, std.array, std.stdio;// Print sorted lines of a file.void main(){auto sortedLines = File("file.txt")// Open for reading .byLineCopy()// Read persistent lines .array()// into an array .sort();// then sort themforeach (line; sortedLines) writeln(line);}
byRecord(Fields...)(stringformat);stringformat | tuple recordformat |
staticimport std.file;import std.typecons : tuple;// prepare test fileauto testFile = std.file.deleteme();scope(failure) printf("Failed test at line %d\n",__LINE__);std.file.write(testFile,"1 2\n4 1\n5 100");scope(exit) std.file.remove(testFile);File f = File(testFile);scope(exit) f.close();auto expected = [tuple(1, 2), tuple(4, 1), tuple(5, 100)];uint i;foreach (e; f.byRecord!(int,int)("%s %s")){ writeln(e);// expected[i++]}
byChunk(size_tchunkSize);byChunk(ubyte[]buffer);Example
void main(){// Read standard input 4KB at a timeforeach (ubyte[]buffer; stdin.byChunk(4096)) { ... usebuffer ... }}The parameter may be a number (as shown in the example above) dictating thesize of each chunk. Alternatively,
byChunk accepts auser-provided buffer that it uses directly.Example
void main(){// Read standard input 4KB at a timeforeach (ubyte[]buffer; stdin.byChunk(newubyte[4096])) { ... usebuffer ... }}In either case, the content of the buffer is reused across calls. That meansfront will not persist afterpopFront is called, so if retention isneeded, the caller must copy its contents (e.g. by calling
buffer.dup).In the example above,buffer.length is 4096 for all iterations, exceptfor the last one, in which casebuffer.length may be less than 4096 (butalways greater than zero).With the mentioned limitations,byChunk works with any algorithmcompatible with input ranges.Example
// Efficient file copy, 1MB at a time.import std.algorithm, std.stdio;void main(){ stdin.byChunk(1024 * 1024).copy(stdout.lockingTextWriter());}std.algorithm.iteration.joiner can be used to join chunks together intoa single range lazily.
Example
import std.algorithm, std.stdio;void main(){//Range of rangesstaticassert(is(typeof(stdin.byChunk(4096).front) ==ubyte[]));//Range of elementsstaticassert(is(typeof(stdin.byChunk(4096).joiner.front) ==ubyte));}
byChunk returns a range initialized with theFileobject and the appropriate buffer.lockingTextWriter();NoteWriting either arrays ofchars orubytes is faster than writing each character individually from a range. For large amounts of data, writing the contents in chunks using an intermediary array can result in a speed increase.
lockingBinaryWriter();ExampleProduce a grayscale image of theMandelbrot setin binaryNetpbm format to standard output.
import std.algorithm, std.complex, std.range, std.stdio;void main(){enum size = 500; writef("P5\n%d %d %d\n", size, size,ubyte.max); iota(-1, 3, 2.0/size).map!(y => iota(-1.5, 0.5, 2.0/size).map!(x =>cast(ubyte)(1+ recurrence!((a, n) => x + y * complex(0, 1) + a[n-1]^^2)(complex(0)) .take(ubyte.max) .countUntil!(z => z.re^^2 + z.im^^2 > 4)) ) ) .copy(stdout.lockingBinaryWriter);}
size();Example
import std.stdio, std.file;void main(){ string deleteme ="delete.me";auto file_handle = File(deleteme,"w"); file_handle.write("abc");//create temporary filescope(exit) deleteme.remove;//remove temporary file at scope exitassert(file_handle.size() == 3);//check if file size is 3 bytes}
LockType: int;readreadWriteisFileHandle(T);staticassert(isFileHandle!(FILE*));staticassert(isFileHandle!(File));
write(T...)(Targs)Targs | the items to write tostdout |
Example Readsstdin and writes it tostdout with an argument counter.
import std.stdio;void main(){ string line;for (size_t count = 0; (line = readln) !isnull; count++) {write("Input ", count,": ", line,"\n"); }}
writeln(T...)(Targs);args, '\n'). Callingwriteln without arguments is valid and just prints a newline to the standard output.Targs | the items to write tostdout |
Example Readsstdin and writes it tostdout with an argument counter.
import std.stdio;void main(){ string line;for (size_t count = 0; (line = readln) !isnull; count++) {writeln("Input ", count,": ", line); }}
writef(alias fmt, A...)(Aargs)writef(Char, A...)(in Char[]fmt, Aargs);Char[]fmt | Theformat string.When passed as a compile-time argument, the string will be statically checkedagainst the argument types passed. |
Aargs | Items to write. |
Note In older versions of Phobos, it used to be possible to write:
writef(stderr,"%s","message");to print a message tostderr. This syntax is no longer supported, and hasbeen superceded by:
stderr.writef("%s","message");
writefln(alias fmt, A...)(Aargs)writefln(Char, A...)(in Char[]fmt, Aargs);readf(alias format, A...)(auto ref Aargs)readf(A...)(scope const(char)[]format, auto ref Aargs);const(char)[]format | Theformat string. When passed as a compile-time argument, the string will be statically checked against the argument types passed. |
Aargs | Items to be read. |
Example
// test.dvoid main(){import std.stdio;foreach (_; 0 .. 3) {int a;readf!" %d"(a); writeln(++a); }}
% echo "1 2 3" | rdmd test.d234
readln(S = string)(dcharterminator = '\n')readln(buf) version, which may offer better performance as it can reuse its read buffer.| S | Template parameter; the type of the allocated buffer, and the type returned. Defaults tostring. |
dcharterminator | Line terminator (by default,'\n'). |
NoteString terminators are not supported due to ambiguity with readln(buf) below.
Example Readsstdin and writes it tostdout.
import std.stdio;void main(){ string line;while ((line =readln()) !isnull) write(line);}
readln(C)(ref C[]buf, dcharterminator = '\n')readln(C, R)(ref C[]buf, Rterminator)terminator.front == (dchar).init)));C[]buf | Buffer used to store the resulting line data. buf is resized as necessary. |
dcharterminator | Line terminator (by default,'\n'). Usestd.ascii.newline for portability (unless the file was opened in text mode). |
Example Readsstdin and writes it tostdout.
import std.stdio;void main(){char[]buf;while (readln(buf)) write(buf);}
readfln(alias format, Data...)(auto ref Datadata);readfln(Data...)(scope const(char)[]format, auto ref Datadata);const(char)[]format | Theformat string. When passed as a compile-time argument, the string will be statically checked against the argument types passed. |
Datadata | Items to be read. |
Example
// sum_rows.dvoid main(){import std.stdio;int a, b, c;while (readfln("%d %d %d", a, b, c) == 3) { writeln(a + b + c); }}
% cat << EOF > input1 2 34 5 67 8 9EOF% rdmd sum_rows.d < input61524
_popen(R1, R2)(R1name, R2mode = "r")lines;Example
void main(){foreach (string line;lines(stdin)) { ... use line ... }}The line terminator ('\n' by default) is part of the string read (itcould be missing in the last line of the file). Several types aresupported forline, and the behavior of
lineschanges accordingly:Example
foreach (ulong i, string line;lines(stdin)) { ... use line ... }In case of an I/O error, anStdioException is thrown.
f, dcharterminator = '\n');Filef | File to read lines from. |
dcharterminator | Line separator ('\n' by default). |
chunks(Filef, size_tsize);Example
void main(){foreach (ubyte[] buffer;chunks(stdin, 4096)) { ... use buffer ... }}The content ofbuffer is reused across calls. In the example above,buffer.length is 4096 for all iterations, except for the last one, in which casebuffer.length may be less than 4096 (but always greater than zero). In case of an I/O error, anStdioException is thrown.
toFile(T)(Tdata, stringfileName)data, stdout.lockingBinaryWriter))));StdioException:object.Exception;errno;message, uinte = core.stdc.errno.errno);opCall(stringmsg);opCall();stdin = makeGlobal!"core.stdc.stdio.stdin".makeGlobal;NoteThe returnedFile wrapscore.stdc.stdio.stdin, and is therefore thread global. Reassigningstdin to a differentFile must be done in a single-threaded or locked context in order to avoid race conditions.
stdin automatically locks the file globally, and will cause all other threads callingread to wait until the lock is released.// Read stdin, sort lines, write to stdoutimport std.algorithm.mutation : copy;import std.algorithm.sorting : sort;import std.array : array;import std.typecons : Yes;void main(){stdin// read from stdin .byLineCopy(Yes.keepTerminator)// copying each line .array()// convert to array of lines .sort()// sort the lines .copy(// copy output of .sort to an OutputRange stdout.lockingTextWriter());// the OutputRange}
stdout = makeGlobal!"core.stdc.stdio.stdout".makeGlobal;NoteThe returnedFile wrapscore.stdc.stdio.stdout, and is therefore thread global. Reassigningstdout to a differentFile must be done in a single-threaded or locked context in order to avoid race conditions.
stdout automatically locks the file globally, and will cause all other threads callingwrite to wait until the lock is released.void main(){stdout.writeln("Write a message to stdout.");}
void main(){import std.algorithm.iteration : filter, map, sum;import std.format : format;import std.range : iota, tee;int len;const r = 6.iota .filter!(a => a % 2)// 1 3 5 .map!(a => a * 2)// 2 6 10 .tee!(_ =>stdout.writefln("len: %d", len++)) .sum; writeln(r);// 18}
void main(){import std.algorithm.mutation : copy;import std.algorithm.iteration : map;import std.format : format;import std.range : iota; 10.iota .map!(e =>"N: %d".format(e)) .copy(stdout.lockingTextWriter());// the OutputRange}
stderr = makeGlobal!"core.stdc.stdio.stderr".makeGlobal;NoteThe returnedFile wrapscore.stdc.stdio.stderr, and is therefore thread global. Reassigningstderr to a differentFile must be done in a single-threaded or locked context in order to avoid race conditions.
stderr automatically locks the file globally, and will cause all other threads callingwrite to wait until the lock is released.void main(){stderr.writeln("Write a message to stderr.");}
openNetwork(stringhost, ushortport);