Поблочный и побайтовый режимы управления файлами, страница 4

n байтов может читаться или записаться в одном запросе.

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

#include <io.h>

      main( ) /* copy input to output */

      {   char buf[BUFSIZ];

           int n;

           while ((n = read(0, buf, BUFSIZ)) > 0)

                write (1, buf, n);

           return 0;

      }

Прототипы функций для работы в поблочном режиме описаны в файле io.h, так что мы можем включать это в программы этой главы.

Параметр BUFSIZ также определен в io.h; ценность - хороший размер для локальной системы. Если размер файла не кратен BUFSIZ, некоторый read возвратит  меньшее число байтов, которые будут записаны.

Поучительно видеть как read и write могут использоваться, чтобы строить установившуюся практику с  более высоким уровнем подобно getchar, putchar, и т.д. Например, имеется версия getchar, которая делает небуфаризированный ввод, читая со стандартного ввод один знак одновременно.

#include <io.h>

      main( ) /* copy input to output */

      {   char buf[BUFSIZ];

           int n;

           while ((n = read(0, buf, BUFSIZ)) > 0)

                write (1, buf, n);

           return 0;

      }

   #include <io.h>

      /* getchar: unbuffered single character input */

      int getchar (void)

      {

           char c;

           return (read(0, &C, 1) => 1) ? (unsigned char) c : EOF;

      }

C должен иметься char, потому что читаемый нуждается в указателе тип знак. Установка c к char без знака в возвращаемом значении устраняет любую проблему расширения знака.

Вторая версия getchar делает вход в больших кусках, и выводит знаки по одному.

#include <io.h>

      /* getchar: simple buffered, version. */

      int getchar(void)

      {   static char buf[BUFSIZ];

           static char *bufp = buf;

           static int n = 0;

           if (n == 0) {   /* buffer is empty */

                n = read (0, buf, sizeof (buf));

                bufp = buf;

           }

           return (--n >= 0) ? (unsigned char) *bufp++ : EOF;

      }

5.II.3. Open, Great, Close, Unlink

Для нестандартных файлов, Вы должен явно их открыть, чтобы читать или писать им. Для этого имеется системный вызов, подобный fopen, обсужденному выше, за исключением того, что вместо возвращения указателя файла, это возвращает описатель файла (handle), который является только int, при открытии возвращение -1 означает, что произошла  ошибка.

    #include <fcntl.h>

    #include <sys\stat.h>

     int fd;

     fd=int open (char *name, int flags, int mode);

Как с fopen, аргумент имени - маршрут, содержащий filename. Второй аргумент, флаги, является int, который определяет, как файл должен быть открыт:

 0_RDONLY - открывается для чтения только,

 0_WRONLY - открываются для письма только,

 0_RDWR - открываются, и для чтения и для письма.

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

Эти константы определены в <fcntl.h>, и в <sys\stat.h>.

Открыть существующий файл для чтения:

           Fd = open ("pfth_of_file", 0_RDONLY, 0);

Аргумент mode - всегда ноль для открытых использований.

 Следующий запрос системы обеспечивает, создание новых файлов, или переделать старые.

           int creat (char *name, int mode);

           Fd = creat ("path", mode);

Возвратил бы описатель файла, если бы файл ,был создан, или -1 если нет. Если файл уже существует, creat обрезает его до нулевой длины, таким образом отказываясь от предыдущего содержания; это - не ошибка создать файл, который уже существует.

Для BORLAND C ++ v. 3.1 мы имеем только одного владельца со спецификацией:

    S_IWRITE - разрешение только, чтобы писать,

    S_IREAD - разрешение только, чтобы читать,

    S_IREAD|S_IWRITE - разрешение читать и писать в файл.

Аргумент MODE в OPEN имеет тоже значение.

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

      #include <stdio.h>

      #include <fcntl.h>

      #include <io.h>

      #define PERMS S_IREAD|S_IWRITE   /* RW for for all users */

      void error (char *, ...);

      /* cp: copy f1 to f2 */

      main (int argc, char *argv[])

      {   int f1, f2, n;

           char buf[BUFSIZ];

           if (argc != 3)

            error( "Usage: cp from to");

           if ((f1 = open(argv[1], 0_RDONLY, 0)) == -1)

                printf ("cp: can't open %s", argv [1]);

           if ((f2 = creat(argv[2], PERMS)) == -1)

                printf ( "cp: can't create %s, mode %03o",

                     argv[2], PERMS);

           while ((n = read(f1, buf, BUFSIZ)) > 0)

                if (write(f2, buf, n) != n)

                     printf( "cp: write error on file %s", argv[2]);

           return 0;

      }

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

Функция

        unlink (char *name);

удаляет имя файла из каталога.

Функция

    long filelength (int *fd);

возвращает длину файла в байтах.

5.II.4. Произвольный доступ - lseek

Ввод и вывод обычно имеют последовательный доступ к файлу. Когда необходимо, однако, файл может читаться или написан в любом произвольном порядке. Запрос системы lseek обеспечивает способ смещаться в файле, чтобы читать или писать  данные с любого места в файле: