Чтение онлайн

на главную - закладки

Жанры

Программирование для Linux. Профессиональный подход

Самьюэл Алекс

Шрифт:

Функция

write
возвращает число записанных байтов или -1, если произошла ошибка. Для некоторых типов файлов чисто фактически записанных байтов может оказаться меньше требуемого. Программа должна выявлять подобные случаи и вызывать функцию
write
повторно, чтобы передать оставшуюся часть данных. Этот прием продемонстрирован в листинге Б.3. Но иногда даже таких методов недостаточно. Например, если показанная функция будет записывать данные в сокет, в нее придется добавить код проверки того, не произошел ли в ходе операции записи разрыв соединения.

Листинг Б.3. (write-all.c) Запись буфера

/* Запись указанного
числа байтов (COUNT) из буфера BUFFER

в файл FD. В случае ошибки возвращается -1,

иначе -- число записанных байтов. */

ssize_t write_all(int fd, const void* buffer, size_t count) {

 size_t left_to_write = count;

 while (left_to_write > 0) {

size_t written = write(fd, buffer, count);

if (written == -1)

/* Произошла ошибка, завершаем работу. */

return -1;

else

/* подсчитываем число оставшихся байтов. */

left_to_write -= written;

 }

 /* Нельзя записать больше, чем COUNT байтов! */

 assert(left_to_write == 0);

 /* Число записанных байтов равно COUNT. */

 return count;

}

Б.1.4. Чтение данных

Функция, осуществляющая чтение данных из файла, называется

read
. Подобно функции
write
, она принимает дескриптор файла, указатель на буфер и счетчик числа извлекаемых байтов. Функция возвращает число прочитанных байтов или -1 в случае ошибки. Иногда читается меньше байтов, чем требовалось, если, например, в файле содержится недостаточно байтов.

Чтение текстовых файлов DOS/Windows

В Linux-программах нередко приходится читать файлы, созданные в DOS или Windows. Важно понимать разницу между тем, как структурируются текстовые файлы в Linux и в DOS/Windows.

В Linux каждая строка текстового файла оканчивается символом новой строки. Он представляется символьной константой

'\n'
, ASCII-код которой равен 10. В Windows строки разделяются двухсимвольной комбинацией символ возврата каретки (константа
'\r'
, ASCII-код 13), за которым идет символ новой строки.

Некоторые текстовые редакторы Linux при отображении текстовых файлов Windows ставят в конце каждой строки обозначение

^M
— символ возврата каретки. В Emacs такие файлы отображаются правильно, но в строке режима появляется запись
(DOS)
. Многие Windows-редакторы, например Notepad (Блокнот), показывают содержимое текстовых файлов Linux в виде одной длинной строки, так как предполагают наличие в конце строки символа возврата каретки.

Если программа читает текстовые файлы, сгенерированные Windows-программами, желательно менять последовательность

'\r\n'
одним символом новой строки. Точно так же при записи текстовых файлов, которые будут читаться Windows-программами, нужно менять одиночные символы новой строки комбинациями
'\r\n'
.

В листинге Б.4 демонстрируется применение функции

read
. Программа отображает шестнадцатиричный дамп файла, заданного в командной строке. В каждой строке показано смещение от начала файла, а затем — следующие 16 байтов.

Листинг Б.4. (hexdump.c) Отображение шестнадцатеричного
дампа файла

#include <fcntl.h>

#include <stdio.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <unistd.h>

int main(int argc, char* argv[]) {

 unsigned char buffer[16];

 size_t offset = 0;

 size_t bytes_read;

 int i;

 /* Открытие файла для чтения. */

 int fd = open(argv[1], O_RDONLY);

 /* Чтение данных из файла по одному блоку за раз. Чтение

продолжается до тех пор, пока размер очередной порции байтов

не окажется меньше размера буфера. Это свидетельствует

о достижении конца буфера. */

 do {

/* чтение следующей строки байтов. */

bytes_read = read(fd, buffer, sizeof(buffer));

/* Отображение смещения, а затем самих байтов. */

printf("0x%06x : ", offset);

for (i = 0; i < bytes_read; ++i)

printf("%02x ", buffer[i]);

printf("\n");

/* Вычисление позиции в файле. */

offset += bytes_read;

 }

 while (bytes_read == sizeof(buffer));

 /* Конец работы. */

 close(fd);

 return 0;

}

Ниже показаны результаты работы программы. Она выводит дамп самой себя.

% ./hexdump hexdump

0x000000 : 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00

0x000010 : 02 00 03 00 01 00 00 00 c0 B3 04 0B 34 00 00 00

0x000020 : e8 23 00 00 00 00 00 00 34 00 20 00 06 00 28 00

0x000030 : 1d 00 1a 00 06 00 00 00 34 00 00 00 34 80 04 08

...

Эти результаты могут быть разными в зависимости от того, какой компилятор применялся и какие флаги компиляции были установлены.

Б.1.5. Перемещение по файлу

В файловом дескрипторе запоминается текущая позиция в файле. При чтении или записи данных указатель текущей позиции перемещается на то количество байтов, которое было прочитано или записано. Но иногда нужно осуществлять простое перемещение по файлу (позиционирование). Например, может потребоваться вернуться в начало файла и прочитать его заново, не открывая повторно.

Позиционирование указателя текущей позиции файла осуществляет функция

lseek
. Она принимает дескриптор файла и два дополнительных аргумента, определяющих новую позицию указателя.

■ Если третий аргумент равен

SEEK_SET
, функция
lseek
интерпретирует второй аргумент как смещение (в байтах) от начала файла.

■ Если третий аргумент равен

SEEK_CUR
, функция
lseek
интерпретирует второй аргумент как смещение (положительное или отрицательное) от текущей позиции.

Поделиться:
Популярные книги

Черный дембель. Часть 5

Федин Андрей Анатольевич
5. Черный дембель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Черный дембель. Часть 5

30 сребреников

Распопов Дмитрий Викторович
1. 30 сребреников
Фантастика:
попаданцы
альтернативная история
фэнтези
фантастика: прочее
5.00
рейтинг книги
30 сребреников

Жребий некроманта 2

Решетов Евгений Валерьевич
2. Жребий некроманта
Фантастика:
боевая фантастика
6.87
рейтинг книги
Жребий некроманта 2

Охота на разведенку

Зайцева Мария
Любовные романы:
современные любовные романы
эро литература
6.76
рейтинг книги
Охота на разведенку

Чужбина

Седой Василий
2. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чужбина

Возвышение Меркурия. Книга 4

Кронос Александр
4. Меркурий
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Возвышение Меркурия. Книга 4

Надуй щеки! Том 3

Вишневский Сергей Викторович
3. Чеболь за партой
Фантастика:
попаданцы
дорама
5.00
рейтинг книги
Надуй щеки! Том 3

Идеальный мир для Лекаря 16

Сапфир Олег
16. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 16

По воле короля

Леви Кира
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
По воле короля

Он тебя не любит(?)

Тоцка Тала
Любовные романы:
современные любовные романы
7.46
рейтинг книги
Он тебя не любит(?)

Курсант: назад в СССР 9

Дамиров Рафаэль
9. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Курсант: назад в СССР 9

Штуцер и тесак

Дроздов Анатолий Федорович
1. Штуцер и тесак
Фантастика:
боевая фантастика
альтернативная история
8.78
рейтинг книги
Штуцер и тесак

Камень Книга седьмая

Минин Станислав
7. Камень
Фантастика:
фэнтези
боевая фантастика
6.22
рейтинг книги
Камень Книга седьмая

Хозяйка дома в «Гиблых Пределах»

Нова Юлия
Любовные романы:
любовно-фантастические романы
5.75
рейтинг книги
Хозяйка дома в «Гиблых Пределах»