Читать интересную книгу Основы программирования в Linux - Мэтью Нейл

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 42 43 44 45 46 47 48 49 50 ... 324

□ 0 — стандартный ввод;

□ 1 — стандартный вывод;

□ 2 — стандартный поток ошибок.

Вы можете связать с файлами и устройствами другие дескрипторы файлов, используя системный вызов open, который уже обсуждался вкратце. Дескрипторы файлов, открытые автоматически, уже позволяют вам создавать простые программы с помощью вызова write.

write

Системный вызов write предназначен для записи из buf первых nbytes байтов в файл, ассоциированный с дескриптором fildes. Он возвращает количество реально записанных байтов, которое может быть меньше nbytes, если в дескрипторе файла обнаружена ошибка или дескриптор файла, расположенный на более низком уровне драйвера устройства, чувствителен к размеру блока. Если функция возвращает 0, это означает, что ничего не записано; если она возвращает -1, в системном вызове write возникла ошибка, которая описывается в глобальной переменной errno,

Далее приведена синтаксическая запись.

<b>#include &lt;unistd.h&gt;</b>

<b>size_t write(int fildes, const void *buf, size_t nbytes);</b>

Благодаря полученным знаниям вы можете написать свою первую программу, simple_write.c:

#include &lt;unistd.h&gt;

#include &lt;stdlib.h&gt;

int main() {

 if ((write(1, &quot;Here is some datan&quot;, 18)) != 18)

  write(2, &quot;A write error has occurred on file descriptor 1n&quot;, 46);

 exit(0);

}

Эта программа просто помещает сообщение в стандартный вывод. Когда она завершается, все открытые дескрипторы файлов автоматически закрываются, и вам не нужно закрывать их явно. Но в случае буферизованного вывода это не так.

$ <b>./simple_write</b>

Here is some data

$

И еще одно маленькое замечание: вызов write может сообщить о том, что записал меньше байтов, чем вы просили. Это не обязательно ошибка. В ваших программах вам придется для выявления ошибок проверить переменную errno и еще раз вызвать write для записи оставшихся данных.

read

Системный вызов read считывает до nbytes байтов данных из файла, ассоциированного с дескриптором файла fildes, и помещает их в область данных buf. Он возвращает количество действительно прочитанных байтов, которое может быть меньше требуемого количества. Если вызов read возвращает 0, ему нечего считывать; он достиг конца файла. Ошибка при вызове заставляет его вернуть -1.

<b>#include &lt;unistd.h&gt;</b>

<b>size_t read(int fildes, void *buf, size_t nbytes);</b>

Программа simple_read.c копирует первые 128 байтов стандартного ввода в стандартный вывод. Она копирует все вводимые данные, если их меньше 128 байтов.

#include &lt;unistd.h&gt;

#include &lt;stdlib.h&gt;

int main() {

 char buffer[128];

 int nread;

 nread = read(0, buffer, 128);

 if (nread == -1)

  write(2, &quot;A read error has occurredn&quot;, 26);

 if ((write(1, buffer, nread)) != nread)

  write(2, <i>&quot;A</i> write error has occurredn&quot;, 27);

 exit(0);

}

Если вы выполните программу, то получите следующий результат:

$ echo <b>hello there | ./simple_read</b>

hello there

$ <b>./simple_read &lt; draft1.txt</b>

Files

In this chapter we will be looking at files and directories and how to

manipulate them. We will learn how to create files, $

Первое выполнение программы с помощью команды echo формирует некоторый ввод программы, который по каналу передается в вашу программу. Во втором выполнении вы перенаправляете ввод из файла draft1.txt. В этом случае вы видите первую часть указанного файла, появляющуюся в стандартном выводе.

Примечание

Обратите внимание на то, что знак подсказки или приглашения командной оболочки появляется в конце последней строки вывода, поскольку в этом примере 128 байтов не формируют целое число строк.

open

Для создания дескриптора нового файла вы должны применить системный вызов open.

<b>#include &lt;fcntl.h&gt;</b>

<b>#include &lt;sys/types.h&gt;</b>

<b>#include &lt;sys/stat.h&gt;</b>

<b>int open(const char *path, int oflags);</b>

<b>int open(const char *path, int oflags, mode_t mode);</b>

Примечание

Строго говоря, для использования вызова open вы не должны включать файлы sys/types.h и sys/stat.h в системах, удовлетворяющих стандартам POSIX, но они могут понадобиться в некоторых системах UNIX.

Не вдаваясь в подробности, скажем, что вызов open устанавливает путь к файлу или устройству. Если установка прошла успешно, он возвращает дескриптор файла, который может применяться в системных вызовах read, write и др. Дескриптор файла уникален и не используется совместно другими процессами, которые могут в данный момент выполняться. Если файл открыт одновременно в двух программах, они поддерживают отдельные дескрипторы файла. Если они обе пишут в файл, то продолжат запись с того места, где остановились. Их данные не чередуются, но данные одной программы могут быть записаны поверх данных другой. У каждой программы свое представление о том, какая порция файла (каково смещение текущей позиции в файле) прочитана или записана. Вы можете помешать нежелательным накладкам такого сорта с помощью блокировки файла, которая будет обсуждаться в главе 7.

1 ... 42 43 44 45 46 47 48 49 50 ... 324
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Основы программирования в Linux - Мэтью Нейл.

Оставить комментарий