Libs-dev/libio/ru

From KolibriOS wiki
Jump to navigation Jump to search

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

По умолчанию, библиотека комплируется с поддержкой имён файлов в OEM кодировке. Поддержка имён файлов в Unicode присутствует, однако требует изменения включаемого файла и пересборки библиотеки.

В большинстве случаев, libio следует прототипам функций POSIX. Для каждой функции, где это возможно, указан её POSIX эквивалент.

Функции (перебор файлов)

file_find_first

Найти первый файл с соответствующими атрибутами и маской в указанной директории.

Прототип:

proc file.find_first _dir, _mask, _attr

Агрументы:

_dir → asciiz
директория, в которой нужно производить поиск
_mask → asciiz
маска файла, с использованием шаблонных символов
_attr → dword
маска атрибутов файла (комбинация констант FA_*)

Результат:

eaxFileInfo*
0 (ошибка) / указатель на структуру с информацией о найденном файле (используется как дескриптор поиска)

file_find_next

Найти следующий файл, соответствующий критериям.

Прототип:

proc file.find_next _findd

Аргументы:

_finddFileInfo*
дескриптор поиска (см. file_find_first)

Результат:

eaxFileInfo*
0 (ошибка) / указатель на структуру с информацией о найденном файле (используется как дескриптор поиска)

file_find_close

Закрыть дескриптор поиска и освободить память.

Прототип:

proc file.find_close _findd

Аргументы:

_finddFileInfo*
дескриптор поиска (см. file_find_first)

Результат:

eax → dword
код возврата функции освобождения памяти

Функции (работа с отдельным файлом)

file_size

Получить размер файла.

Прототип:

proc file.size _name

Аргументы:

_name → asciiz
путь к файлу (абсолютный или относительный)

Результат:

ebx (обратите внимание ebx, а не eax) → dword
-1 (ошибка) / размер файла (в байтах, до 2 гигабайт)

Замечания:

используйте file_err для получения расширенной информации об ошибке

file_open

Открыть файл.

Прототип:

proc file.open _name, _mode

Аргументы:

_name → asciiz
путь к файлу (абсолютный или относительный)
_mode → dword
режим работы с файлом (комбинация констант O_*)

Результат:

eax → InternalFileInfo*
0 (ошибка) / дескриптор файла

Замечания:

используйте file_err для получения расширенной информации об ошибке

POSIX эквивалент:

FILE *result = fopen(_name, _mode);

file_read

Прочитать данные из файла.

Прототип:

proc file.read _filed, _buf, _buflen

Аргументы:

_filed → InternalFileInfo*
дескриптор файла (см. file_open)
_buf → byte*
буфер для размещения прочитанных данных
_buflen → dword
размер буфера (количество байт, которое необходимо прочитать)

Результат:

eax → dword
-1 (ошибка) / количество прочитанных байт

Замечания:

используйте file_err для получения расширенной информации об ошибке

POSIX эквивалент:

size_t result = fread(_buf, _buflen, 1, _filed);

file_write

Записать данные в файл.

Прототип:

proc file.write _filed, _buf, _buflen

Аргументы:

_filed → InternalFileInfo*
дескриптор файла (см. file_open)
_buf → byte*
буфер с данными для записи
_buflen → dword
размер буфера (количество байт, которое необходимо записать)

Результат:

eax → dword
-1 (ошибка) / количество записанных байт

Замечания:

используйте file_err для получения расширенной информации об ошибке

POSIX эквивалент:

size_t result = fwrite(_buf, _buflen, 1, _filed);

file_seek

Установить позицию файлового указателя.

Прототип:

proc file.seek _filed, _where, _origin

Аргументы:

_filed → InternalFileInfo*
дескриптор файла (см. file_open)
_where → dword
смещение в файле (в байтах) начиная от указанного исходного места
_origin → dword
исходное место, от которого рассчитывается позиция (одна из констант SEEK_*)

Результат:

eax → dword
-1 (ошибка) / 0

Замечания:

используйте file_err для получения расширенной информации об ошибке

POSIX эквивалент:

int result = fseek(_filed, _where, _origin);

file_iseof

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

Прототип:

proc file.eof? _filed

Аргументы:

_filed → InternalFileInfo*
дескриптор файла (см. file_open)

Результат:

eax → dword
ложь / истина

Замечания:

используйте file_err для получения расширенной информации об ошибке

POSIX эквивалент:

int result = feof(_filed);

file_truncate (file_seteof)

Установить размер файла в текущее значение позиции файлового указателя.

Прототип:

proc file.truncate _filed

Аргументы:

_filed → InternalFileInfo*
дескриптор файла (см. file_open)

Результат:

eax → dword
-1 (ошибка) / 0

Замечания:

используйте file_err для получения расширенной информации об ошибке

POSIX эквивалент:

int result = ftruncate(fileno(_filed), ftell(_filed));

file_tell

Получить текущее значение позиции файлового указателя.

Прототип:

proc file.tell _filed

Аргументы:

_filed → InternalFileInfo*
дескриптор файоа (см. file_open)

Результат:

eax → dword
-1 (ошибка) / позиция файлового указателя

Замечания:

используйте file_err для получения расширенной информации об ошибке

POSIX эквивалент:

long result = ftell(_filed);

file_close

Закрыть файл.

Прототип:

proc file.close _filed

Аргументы:

_filed → InternalFileInfo*
дескриптор файла (см. file_open)

Результат:

eax → dword
-1 (ошибка) / 0

Замечания:

используйте file_err для получения расширенной информации об ошибке

POSIX эквивалент:

int result = fclose(_filed);

file_err

Получить расширенную информацию об ошибке. Увы, функция пока не существует.

Константы

Режим открытия файла

<source> O_BINARY = 00000000b O_READ = 00000001b O_WRITE = 00000010b O_CREATE = 00000100b O_SHARE = 00001000b O_TEXT = 00010000b </source>

Детальное описание:

O_BINARY
ни коим образом не изменять читаемые/записываемые данные (по умолчанию)
O_READ
открыть файл для чтения
O_WRITE
открыть файл для записи
O_CREATE
создать файл, если его не существует; иначе, открыть уже существующий
O_SHARE
разрешить параллельный доступ в файлу, используя разные дескрипторы (не реализовано)
O_TEXT
заменять символы конца строки на LF (замещает O_BINARY, не реализовано)

Исходное место перемещения по файлу

<source> SEEK_SET = 0 SEEK_CUR = 1 SEEK_END = 2 </source>

Детальное описание:

SEEK_SET
от начала файла
SEEK_CUR
от текущей позиции файлового указателя
SEEK_END
от конца файла

Атрибуты файла

<source> FA_READONLY = 00000001b FA_HIDDEN = 00000010b FA_SYSTEM = 00000100b FA_LABEL = 00001000b FA_FOLDER = 00010000b FA_ARCHIVED = 00100000b FA_ANY = 00111111b </source>

Детальное описание:

FA_READONLY
файл только для чтения (запись запрещена)
FA_HIDDEN
файл или директория скрыты (обычно, невидимы для пользователя)
FA_SYSTEM
файл или директория содержат важные данные операционной системы
FA_LABEL
не файл, имя содержит метку диска
FA_FOLDER
не файл, но директория
FA_ARCHIVED
архивный файл (устаревший флаг, используется системой)
FA_ANY
любой из перечисленных атрибутов (используется для указания маски)

Структуры

FileDateTime

Дата и время в формате, возвращаемом системными вызовами.

<source> struct FileDateTime

 union
   time    dd ?
   struct
     sec   db ?
     min   db ?
     hour  db ?
   ends
 ends
 union
   date    dd ?
   struct
     day   db ?
     month db ?
     year  dw ?
   ends
 ends

ends </source>

FileInfoBlock

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

<source> struct FileInfoBlock

 Function   dd ?
 Position   dd ?
 Flags      dd ?
 Count      dd ?
 Buffer     dd ?
            db ?
 FileName   dd ?

ends </source>

FileInfoHeader

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

<source> struct FileInfoHeader

 Version    dd ?
 FilesRead  dd ?
 FilesCount dd ?
            rd 5

ends </source>

FileInfoA

OEM версия структуры FileInfo (блока данных входа каталога).

<source> struct FileInfoA

 Attributes   dd ?
 Flags        dd ?
 DateCreate   FileDateTime
 DateAccess   FileDateTime
 DateModify   FileDateTime
 union
   FileSize   dq ?
   struct
     FileSizeLow  dd ?
     FileSizeHigh dd ?
   ends
 ends
 FileName     rb 264

ends </source>

FileInfoW

Unicode версия структуры FileInfo (блока данных входа каталога).

<source> struct FileInfoW

 Attributes   dd ?
 Flags        dd ?
 DateCreate   FileDateTime
 DateAccess   FileDateTime
 DateModify   FileDateTime
 union
   FileSize   dq ?
   struct
     FileSizeLow  dd ?
     FileSizeHigh dd ?
   ends
 ends
 FileName     rw 260

ends </source>

Примеры использования

Небольшой кусок кода, иллюстрирующий открытие файла, чтение 256 байт, перемещения указателя в начало файла, запись прочитанных данных и закрытие дескриптора файла. Заметьте, что может быть успешно прочитано менее 256 байт, поэтому мы запоминаем точное число. Заметьте также, что мы используем "invoke", так как вызов функции — косвенный.

<source line> include 'libio/libio.inc'

...
       invoke  file_open, filename, O_READ + O_WRITE
       or      eax, eax
       jz      .error
       mov     [fdesc], eax

       invoke  file_read, eax, buffer, 256
       mov     [bytes_read], eax
       inc     eax
       jz      .close
       invoke  file_seek, [fdesc], 0, SEEK_SET
       inc     eax
       jz      .close
       invoke  file_write, [fdesc], buffer, [bytes_read]
 .close:
       invoke  file_close, [fdesc]

 .error:
...

filename db '/hd0/1/a.dat', 0 fdesc dd ? bytes_read dd ? buffer db 256 dup(?) </source>

Тот же самый код на языке C может выглядеть так (для сравнения):

<source lang="c" line>

   FILE *f = file_open("/hd0/1/a.dat", O_READ | O_WRITE);
   if (f)
   {
       do
       {
           char buffer[256];
           size_t bytes_read = file_read(f, buffer, sizeof(buffer));
           if (bytes_read == -1)
           {
               break;
           }
           if (file_seek(f, 0, SEEK_SET) == -1)
           {
               break;
           }
           file_write(f, buffer, bytes_read);
       }
       while (0);
       file_close(f);
   }

</source>