Системное программирование в среде Windows | страница 26



Программа 1.1. срC: копирование файлов с использованием библиотеки С

>/* Глава 1. Базовая программа копирования файлов cp. Реализация, использующая библиотеку С. */

>/* cp файл1 файл2: Копировать файл1 в файл2. */

>#include

>#include

>#define BUF_SIZE 256


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

> FILE *in_file, *out_file;

> char rec [BUF_SIZE];

> size_t bytes_in, bytes_out;

> if (argc != 3) {

>  printf("Использование: срС файл1 файл2\n");

>  return 1;

> }

> in_file = fopen(argv [1], "rb");

> if (in_file == NULL) {

>  perror(argv[1]);

>  return 2;

> }

> out_file = fopen(argv [2], "wb");

> if (out_file == NULL) {

>  perror(argv [2]);

>  return 3;

> }

> /* Обработать входной файл по одной записи за один раз. */

> while ((bytes_in = fread(rec, 1, BUF_SIZE, in_file)) > 0) {

>  bytes_out = fwrite(rec, 1, bytes_in, out_file);

>  if (bytes_out != bytes_in) {

>   perror("Неустранимая ошибка записи.");

>   return 4;

>  }

> }

> fclose (in_file);

> fclose (out_file);

> return 0;

>}

Этот простой пример может служить наглядной иллюстрацией ряда общепринятых допущений и соглашений программирования, которые не всегда применяются в Windows.

1. Объекты открытых файлов идентифицируются указателями на структуры FILE (в UNIX используются целочисленные дескрипторы файлов). Указателю NULL соответствует несуществующий объект. По сути, указатели являются разновидностью дескрипторов объектов открытых файлов.

2. В вызове функции fopen указывается, каким образом должен обрабатываться файл — как текстовый или как двоичный. В текстовых файлах содержатся специфические для каждой системы последовательности символов, используемых, например, для обозначения конца строки. Во многих системах, включая Windows, в процессе выполнения операций ввода/вывода каждая из таких последовательностей автоматически преобразуется в нулевой символ, который интерпретируется в языке С как метка конца строки, и наоборот. В нашем примере оба файла открываются как двоичные.

3. Диагностика ошибок реализуется с помощью функции perror, которая, в свою очередь, получает информацию относительно природы сбоя, возникающего при вызове функции fopen, из глобальной переменной errno. Вместо этого можно было бы воспользоваться функцией ferror, возвращающей код ошибки, ассоциированный не с системой, а с объектом FILE.

4. Функции fread и fwrite возвращают количество обработанных байтов непосредственно, а не через аргумент, что оказывает существенное влияние на логику организации программы. Неотрицательное возвращаемое значение говорит об успешном выполнении операции чтения, тогда как нулевое — о попытке чтения метки конца файла.