| Чтение файла: read() |
|
Для чтения файлов служит системный вызов reado, объявленный в файле unistd.h следующим образом: ssize_t read (int FD, void * BUFFER, size„t SIZE); Этот системный вызов пытается прочитать size байт из файла с дескриптором fd. Прочитанная информация заносится в buffer. Возвращаемое значение — число реально прочитанных байтов. Аргумент size_t — это беззнаковый целый тип, размерность которого зависит от реализации, ssize_t тоже является целым, но уже знаковым типом. Указание именно ssize_t обусловлено тем, что read() возвращает -1 в случае ошибки. Когда текущая позиция ввода-вывода достигает конца файла, read() возвращает 0. В качестве буфера может выступать практически любой блок памяти известного размера. Но чаще всего в системном вызове read() используются строки. Рассмотрим пример программы, которая выводит на экран содержимое указанного файла, читая его посимвольно при помощи системного вызова read() Программа readl.c #include <stdio.h> Итак, в качестве буфера был передан адрес переменной типа char, и чтение осуществлялось по одному байту. Такая схема проста, но очень неэффективна. Обращение к системному вызову read О для чтения каждого символа значительно замедляет работу программы. Только представьте себе: чтобы прочитать файл размером 1 Кбайт, программа обращается к ядру 1024 раза! Поэтому файлы лучше читать достаточно большими блоками. Обычно для этих целей создается буфер размером в несколько килобайт. Напишем теперь программу, которая делает то же, что и предыдущая, только более эффективным способом Программа read2.c #include <stdio.h> В этой версии программы появилась новая переменная bytes, в которую записывается размер прочитанной информации. Буфером является массив buffer. Обратите внимание, что каждый раз в конец этого массива дописывается нуль-терминатор. Это обусловлено тем, что вывод осуществляется функцией printf о, для которой признаком окончания вывода служит символ с кодом 0. Всегда следует помнить, что системный вызов read() просто читает байты, а ответственность за формирование строки возложена на программиста. Функция printf о предназначена для вывода данных на экран терминала. Поэтому она не может воспринимать некоторые байты "как есть". Рассмотрим следующую команду: $ ./readl fool > foo2 В этом случае файл fool будет скопирован в foo2, если исходный файл не содержит определенные символы, которые printf о воспринимает как команды форматирования (звонок, символ с кодом 0 и т. д.). В связи с этим, программа readl не может быть универсальным средством копирования файлов. Напишем еще одну программу, упрощенную версию утилиты ср, которая будет осуществлять полноценное копирование файла Программа копирования файлов #include <stdio.h>
Эта программа реализует вывод с помощью функции fputc(), которая безразлична к любым символам. В данном случае запись данных осуществляется посимвольно в цикле, поэтому нет необходимости устанавливать нуль-терминатор.
Related Articles
Set as favorite
Bookmark
Email This
Hits: 468 Комментарии (0)RSS feed CommentsНаписать комментарий |