Переместиться к: chunks · File · isFileHandle · KeepTerminator · lines · LockType · openNetwork · popen · readf · readln · stderr · stdin · StdioException · stdout · toFile · write · writef · writefln · writeln
stdio
. Модуль core.stdc.stdio
публично импортируется при импорте std.stdio
.
Исходный код: std/stdio.d
KeepTerminator
= std.typecons.Flag!"keepTerminator".Flag;
KeepTerminator
установлен на KeepTerminator
.yes, тогда разделитель включается в возвращаемые строки.Переместиться к: byChunk · byLine · byLineCopy · byRecord · clearerr · close · detach · eof · error · fdopen · fileno · flush · getFP · isOpen · lock · lockingBinaryWriter · lockingTextWriter · name · opAssign · open · popen · rawRead · rawWrite · readf · readln · reopen · rewind · seek · setvbuf · size · sync · tell · this · tmpfile · tryLock · unlock · windowsHandle · windowsHandleOpen · wrapFile · write · writef · writefln · writeln
File
;
File
гарантирует безопасную обработку, автоматическое закрытие файлов, а также множество удобств.
File
, связанная с данным FILE* выходит из области видимости, нижележащий FILE* автоматически закрыкрывается.
Пример:
// 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 вышел из области видимости, количество ссылок упало до нуля, // лежащий в основе $(D FILE*) закрыт. }
% rdmd test.d Jimmy % cat test.txt Hello, Jimmy! % _
name
, in char[] stdioOpenmode
= "rb");
name
)name
, R2 mode
)name
открываемого файла и режим открытия mode
.
string name |
диапазон или строка, представляющие имя файла |
char[] stdioOpenmode |
диапазон или строка, представляющие режим открытия (с той же семантикой, как в стандартной библиотечной функции fopen в C) |
opAssign
(File rhs
);
open
(string name
, in char[] stdioOpenmode
= "rb");
name
в режиме stdioOpenmode
. Режим имеет ту же семантику, как в стандартной библиотечной функции fopen в C.
reopen
(string name
, in char[] stdioOpenmode
= "rb");
name
равно null, изменяется режим открытого в настоящий момент файла; в противном случае, открывается новый файл, заново используя
FILE* из C. Функция имеет ту же семантику, как в стандартной библиотечной функции freopen
в C.
Замечание:
Вызов reopen
с name
, равным null, реализован не во всех средах выполнения C.
popen
(string command
, in char[] stdioOpenmode
= "r");
command
,
вызывая стандартную библиотечную C-функцию popen.
fdopen
(int fd
, in char[] stdioOpenmode
= "rb");
windowsHandleOpen
(HANDLE handle
, in char[] stdioOpenmode
);
handle
. Только для Windows.
isOpen
();
true
, если файл открыт.eof
();
true
, если файл дошёл до конца (смотрите feof).
name
();
error
();
true
. В противном случае, возвращает
ferror для файла.detach
();
close
();
clearerr
();
flush
();
sync
();
rawRead
(T)(T[] buffer
);
buffer
, содержащий данные, которые были действительно прочитаны. Он будет короче, чем buffer
, если EOF был достигнут до заполнения буфера.
buffer
пуст.
ErrnoException, если файл не открыт, или если вызов fread потерпел неудачу.
В Windows rawRead
всегда читает в двоичном режиме.static import std.file; auto testFile = testFilename(); std.file.write(testFile, "\r\n\n\r\n"); scope(exit) std.file.remove(testFile); auto f = File(testFile, "r"); auto buf = f.rawRead(new char[5]); f.close(); assert(buf == "\r\n\n\r\n");
rawWrite
(T)(in T[] buffer
);
rawWrite
всегда пишет в двоичном режиме.
static import std.file; auto testFile = testFilename(); auto f = File(testFile, "w"); scope(exit) std.file.remove(testFile); f.rawWrite("\r\n\n\r\n"); f.close(); assert(std.file.read(testFile) == "\r\n\n\r\n");
seek
(long offset
, int origin
= SEEK_SET);
tell
();
static import std.file; import std.conv : text; auto testFile = testFilename(); std.file.write(testFile, "abcdefghijklmnopqrstuvwqxyz"); scope(exit) { std.file.remove(testFile); } auto f = File(testFile); auto a = new ubyte[4]; f.rawRead(a); assert(f.tell == 4, text(f.tell));
rewind
();
setvbuf
потерпел неудачу.setvbuf
(void[] buf
, int mode
= _IOFBF);
setvbuf
потерпел неудачу.lock
(LockType lockType
= LockType.readWrite, ulong start
= 0, ulong length
= 0);
lock
не будет отпущен. Если одновременно start
и length
равны нулю, блокируется весь файл.
lock
иtryLock имеет следующие свойства:
tryLock
(LockType lockType
= LockType.readWrite, ulong start
= 0, ulong length
= 0);
start
и length
равны нулю, блокируется весь файл.
true
, если блокировка была успешной, и false
, если определенный сегмент файла уже был заблокирован.unlock
(ulong start
= 0, ulong length
= 0);
write
(S...)(S args
);
writeln
(S...)(S args
);
writef
(Char, A...)(in Char[] fmt
, A args
);
writefln
(Char, A...)(in Char[] fmt
, A args
);
readln
(buf), которая может предложить более высокую производительность, так как она может повторно использовать буфер чтения.
S | Параметр шаблона; тип размещённого буфера, и возвращаемый тип. Установлен по умолчанию в string. |
dchar terminator |
символ перевода строки (по умолчанию, '\n'). |
Замечание:
Строковые терминаторы не поддерживаются из-за неоднозначности с readln
(buf) ниже.
Example:
// Читает $(D stdin) и пишет это в $(D stdout). import std.stdio; void main() { string line; while ((line = stdin.readln()) !is null) write(line); }
readln
(C)(ref C[] buf
, dchar terminator
= '\x0a')readln
(C, R)(ref C[] buf
, R terminator
)terminator
.front == (dchar).init)));
buf
[], включая символ перевода строки.
readln
(), поскольку вы можете многократно использовать буфер для каждого вызова. Заметьте, что повторное использование буфера означает, что вы должны скопировать предыдущее содержимое, если вы хотите сохранить его.
C[] buf |
Буфер, используемый для хранения результирующих данных. buf iизменит размер при необходимости. |
dchar terminator |
символ перевода строки (по умолчанию, '\n'). Используйте std.ascii.newline для портируемости (если файл не был открыт в текстовом режиме). |
Example:
// Читать строки из $(D stdin) в string // Игнорирует строки, начинающиеся с '#' // Пишет string в $(D stdout) void main() { string output; char[] buf; while (stdin.readln(buf)) { if (buf[0] == '#') continue; output ~= buf; } write(output); }Этот метод может быть более эффективным чем в предыдущем примере, поскольку stdin.
readln
(buf
) повторно использует (если возможно) память, распределённую для буфера, поскольку buf
, whereas line = stdin.readln
() распределяет новую память для каждой строки.
Для еще более высокой производительности вы можете помочь readln
, передавая большой буфер, чтобы избежать перераспределений памяти. Это может быть сделано посредством повторного использования самого большого буфера, возвращённого readln
:
Example:
// Читать строки из $(D stdin) считать слова 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); }Это на самом деле то, что внутренне делает byLine, так что рекомендуется его использовать, если вы хотите обработать весь файл.
readf
(Data...)(in char[] format
, Data data
);
data
из файла в соответствии с заданным
описателем формата, используя
std.format.formattedRead.// @system из-за использования readf static import std.file; auto deleteme = testFilename(); 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); assert(s == "hello", "["~s~"]"); f.readf("%s\n", &s); assert(s == "world", "["~s~"]"); // Issue 11698 bool b1, b2; f.readf("%s\n%s\n", &b1, &b2); assert(b1 == true && b2 == false);
tmpfile
();
wrapFile
(FILE* f
);
getFP
();
fileno
();
windowsHandle
();
byLine
(Terminator = char, Char = char)(KeepTerminator keepTerminator
= No.keepTerminator
, Terminator terminator
= '\x0a')byLine
(Terminator, Char = char)(KeepTerminator keepTerminator
, Terminator terminator
)Замечание: Каждое переднее значение (front) не будет сохраняться после вызова popFront, так что вызывающий код должен скопировать его содержимое (например, вызывая to!string) когда сохранение необходимо. Если вызывающему оператору нужно сохранить копию каждой строки, используйте вместо этого функцию byLineCopy.
Char | Тип символов для каждой строки, по-умолчанию char. |
KeepTerminator keepTerminator |
Используйте Yes.keepTerminator чтобы включить
terminator в конце каждой строки. |
Terminator terminator |
Разделитель строк ('\n' по-умолчанию). Используйте std.ascii.newline для портируемости (если файл не был открыт в текстовом режиме). |
Пример:
import std.algorithm, std.stdio, std.string; // Количество слов в файле с использованием диапазонов. void main() { auto file = File("file.txt"); // Открыто для чтения const wordCount = file.byLine() // Прочесть строки .map!split // Разделить на слова .map!(a => a.length) // Подсчитать количество слов в строках .sum(); // Общее количество слов writeln(wordCount); }
Пример:
import std.range, std.stdio; // Количество строк с использованием foreach. void main() { auto file = File("file.txt"); // Открыто для чтения auto range = file.byLine(); // Печать первых трёх строк foreach (line; range.take(3)) writeln(line); // Печать остальных строк, начинающихся с '#' foreach (line; range) { if (!line.empty && line[0] == '#') writeln(line); } }Обратите внимание, что ни один пример не получал доступ к данным строки, возвращаемой front после того, как был сделан соответствующий вызов popFront (поскольку содержание вполне может измениться).
byLineCopy
(Terminator = char, Char = immutable(char))(KeepTerminator keepTerminator
= No.keepTerminator
, Terminator terminator
= '\x0a')byLineCopy
(Terminator, Char = immutable(char))(KeepTerminator keepTerminator
, Terminator terminator
)Замечание:
Из-за кэширования byLineCopy
может быть более эффективной по использованию памяти, чем
File.byLine.map!idup.
Char | Тип символов для каждой строки, по умолчанию immutable char. |
KeepTerminator keepTerminator |
Используйте Yes.keepTerminator , чтобы включить
terminator в конце каждой строки. |
Terminator terminator |
Разделитель строк ('\n' по-умолчанию). Используйте std.ascii.newline для портируемости (если файл не был открыт в текстовом режиме). |
Пример:
import std.algorithm, std.array, std.stdio; // Печать отсортированных строк файла. void main() { auto sortedLines = File("file.txt") // Открыть для чтения .byLineCopy() // Чтение сохраняющихся строк .array() // в массив .sort(); // затем их сортировка foreach (line; sortedLines) writeln(line); }
byRecord
(Fields...)(string format
);
file | дескриптор разбираемого файла |
string format |
Формат записи кортежа |
static import std.file; import std.typecons : tuple; // подготовка тестового файла auto testFile = testFilename(); 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")) { assert(e == expected[i++]); }Я в этом примере так и не понял, где брать функцию testFilename(), поэтому вместо неё просто открыл объект File, передав в него имя файла – прим. пер.
byChunk
(size_t chunkSize
);
byChunk
(ubyte[] buffer
);
Пример:
void main() { // Прочитайть со стандартного входа 4KB за один раз foreach (ubyte[] buffer; stdin.byChunk(4096)) { ... использовать buffer ... } }Параметр может быть числом (как показано в примере выше) предписывающим размер каждого куска. Кроме того,
byChunk
может принимать предоставленный пользователем буфер, который он использует непосредственно.
Пример:
void main() { // Прочитайть со стандартного входа 4KB за один раз foreach (ubyte[] buffer; stdin.byChunk(new ubyte[4096])) { ... использовать buffer ... } }В любом случае, содержимое
buffer
используется повторно в течение всех вызовов. Это означает, что
front не сохраняется после вызова popFront, так что если требуется сохранение, вызывающий код должен скопировать его содержимое (например, вызывая buffer
.dup).
В примере выше, buffer
.length (длина буфера) равна 4096 для всех итераций, за исключением последней, в её случае buffer
.length может быть меньше, чем 4096 (но всегда больше, чем нуль).
С упомянутыми ограничениями, byChunks работает с любым алгоритмом, совместимым с входными диапазонами.
Пример:
// Эффективное копирование файла, по 1MB за один раз. import std.algorithm, std.stdio; void main() { stdin.byChunk(1024 * 1024).copy(stdout.lockingTextWriter()); }Можно использовать std.algorithm.iteration.joiner для ленивого соединения кусков вместе в единственный диапазон.
Пример:
import std.algorithm, std.stdio; void main() { //Диапазон диапазонов static assert(is(typeof(stdin.byChunk(4096).front) == ubyte[])); //Диапазон элементов static assert(is(typeof(stdin.byChunk(4096).joiner.front) == ubyte)); }
byChunk
возвращает диапазон, инициализированный объектом File
и выделенным буфером.
lockingTextWriter
();
lockingBinaryWriter
();
Пример: Формирует изображение в градациях серого множества Мандельброта в двоичном Netpbm-формате на стандартный вывод.
import std.algorithm, 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*1i + a[n-1]^^2)(0+0i) .take(ubyte.max) .countUntil!(z => z.re^^2 + z.im^^2 > 4)) ) ) .copy(stdout.lockingBinaryWriter); }
size
();
read
readWrite
isFileHandle
(T);
static assert(isFileHandle!(FILE*)); static assert(isFileHandle!(File));
write
(T...)(T args
)args
, форматирует аргумент (в соответствии с
to!(string)(arg)) и записывает результирующую строку в args
[0]. Вызов без каких-либо аргументов не будет компилироваться.
T args |
элементы, записываемые в stdout |
writeln
(T...)(T args
);
args
, '\n'). Вызов writeln
без аргументов допустим, и просто печатает новую строку на стандартный вывод.
T args |
элементы, записываемые в stdout |
writef
(T...)(T args
);
T args |
Первым аргументом args [0] должна быть форматирующая строка, определяющая как форматировать остальные аргументы. Для полного описания синтаксиса форматирующей строки, и того, как она управляет форматированием остальных аргументов, пожалуйста обратитесь к документации по std.format.formattedWrite. |
Замечание: Раньше, в более старых версиях Phobos, было возможно написать:
writef(stderr, "%s", "message");чтобы печатать сообщение в stderr. Этот синтаксис не больше не поддерживается, и заменён на:
stderr.writef("%s", "message");
writefln
(T...)(T args
);
args
, '\n').readf
(A...)(in char[] format
, A args
);
readln
(buf), которая может предложить лучшую производительность, так как может многократно использовать свой буфер чтения.
terminator
.
S | Параметр шаблона; тип размещаемого буфера, и возвращаемый тип. Установлен по умолчанию в string. |
dchar terminator |
Символ перевода строки (по умолчанию, '\n'). |
Замечание:
Терминаторы строки не поддерживаются из-за неоднозначности с readln
(buf) ниже.
Пример: Читает stdin и записывает в stdout.
import std.stdio; void main() { string line; while ((line = readln()) !is null) write(line); }
readln
(C)(ref C[] buf
, dchar terminator
= '\x0a')readln
(C, R)(ref C[] buf
, R terminator
)terminator
.front == (dchar).init)));
buf
[], включая символ перевода строки.
readln
(), поскольку вы можете многократно использовать буфер для каждого вызова. Заметьте, что повторное использование буфера означает, что вы должны скопировать предыдущее содержимое, если вам нужно его сохранить.
C[] buf |
Буфер, используемый для хранения данных полученной строки. buf изменит размеры при необходимости. |
dchar terminator |
Символ перевода строки (по умолчанию, '\n'). Используйте std.ascii.newline для портируемости (если файл не был открыт в текстовом режиме). |
Пример: Читает stdin и записывает в stdout.
import std.stdio; void main() { char[] buf; while (readln(buf)) write(buf); }
popen
(R1, R2)(R1 name
, R2 mode
= "r")popen
с соответственно построенными строками в стиле С.Пример:
void main() { foreach (string line; lines(stdin)) { ... use line ... } }Символ перевода строки (по умолчанию '\n' ) является частью прочитанной строки (он может отсутствовать в последней строке файла). Для строки line поддерживается несколько типов, и поведение
lines
изменяется соответственно:
Пример:
foreach (ulong i, string line; lines(stdin)) { ... use line ... }В случае ошибки ввода/вывода, бросается исключение StdioException.
f
, dchar terminator
= '\x0a');
File f |
Файл для построчного чтения. |
dchar terminator |
Разделитель строк (по-умолчанию '\n'). |
chunks
(File f
, size_t size
);
Пример:
void main() { foreach (ubyte[] buffer; chunks(stdin, 4096)) { ... use buffer ... } }Содержимое буфера buffer перезаписывается при вызовах. В примере выше, buffer.length равно 4096 для всех итераций, за исключением последней, в этом случае buffer.length может быть меньше, чем 4096 (но всегда больше, чем нуль). В случае ошибки ввода/вывода, бросается исключение StdioException.
toFile
(T)(T data
, string fileName
)data
, stdout.lockingBinaryWriter))));
data
.copy(File(fileName
, "wb").lockingBinaryWriter).
Подобно std.file.write, строки записываются как есть, а не кодируются в соответствии с ориентацией файла.errno
;
message
, uint e
= core.stdc.errno.errno);
message
и кодом ошибки.opCall
(string msg
);
opCall
();
stdin
;
stdin
в другой экземпляр File, кроме встроенного, не является потокобезопасным.// Чтение stdin, сортировка строк, запись в stdout import std.stdio, std.array, std.algorithm : sort, copy; void main() { stdin // чтение из stdin .byLineCopy(Yes.keepTerminator) // копирование каждой строки .array() // преобразование в массив строк .sort() // сортировка строк .copy( // копирование вывода .sort в выходной диапазон stdout.lockingTextWriter()); // выходной диапазон }
stdout
;
stdout
в другой экземпляр File, кроме встроенного, не является потокобезопасным.stderr
;
stderr
в другой экземпляр File, кроме встроенного, не является потокобезопасным.openNetwork
(string host
, ushort port
);
host
и порту port
, затем возвращает структуру File с доступом на чтение и запись через такой же интерфейс, как с любым другим файлом (это означает, что writef и диапазоны Byline работают!).