Вход/Регистрация
Программирование для Linux. Профессиональный подход
вернуться

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

Шрифт:

 /* Открытие файла для записи. Если файл существует, он

открывается в режиме добавления; в противном случае

файл создается. */

 int fd =

open(filename. O_WRONLY | O_CREAT | O_APPEND, 0666);

 /* Вычисление длины строки с меткой времени. */

 size_t length = strlen(timestamp);

 /* Запись метки времени в файл. */

 write(fd, timestamp, length);

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

 close(fd);

 return 0;

}

Вот как работает программа:

% ./timestamp tsfile

% cat tsfile

The Feb 1 23:25:20 2001

% ./timestamp tsfile

% cat tsfile

Thu Feb 1 23:25:20 2001

Thu Feb 1 23:25:47 2001

Обратите внимание на то, что при первом вызове программы

timestamp
файл был создан, а при втором вызове — дополнен.

Функция

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);

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

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

  • Читать дальше
  • 1
  • ...
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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