Libs-dev/libio/ru

From KolibriOS wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

В настоящий момент, 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

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

Константы

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

O_BINARY = 00000000b
O_READ   = 00000001b
O_WRITE  = 00000010b
O_CREATE = 00000100b
O_SHARE  = 00001000b
O_TEXT   = 00010000b

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

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

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

SEEK_SET = 0
SEEK_CUR = 1
SEEK_END = 2

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

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

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

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

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

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

Структуры

FileDateTime

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

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

FileInfoBlock

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

struct FileInfoBlock
  Function   dd ?
  Position   dd ?
  Flags      dd ?
  Count      dd ?
  Buffer     dd ?
             db ?
  FileName   dd ?
ends

FileInfoHeader

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

struct FileInfoHeader
  Version    dd ?
  FilesRead  dd ?
  FilesCount dd ?
             rd 5
ends

FileInfoA

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

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

FileInfoW

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

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

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

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

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(?)

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

 1    FILE *f = file_open("/hd0/1/a.dat", O_READ | O_WRITE);
 2    if (f)
 3    {
 4        do
 5        {
 6            char buffer[256];
 7            size_t bytes_read = file_read(f, buffer, sizeof(buffer));
 8            if (bytes_read == -1)
 9            {
10                break;
11            }
12            if (file_seek(f, 0, SEEK_SET) == -1)
13            {
14                break;
15            }
16            file_write(f, buffer, bytes_read);
17        }
18        while (0);
19        file_close(f);
20    }