Libs-dev/libio/ru
В настоящий момент, libio предоставляет API только для работы с файлами (хотя изначально в планах были также и другие типы взаимодействия, например, шины).
По умолчанию, библиотека комплируется с поддержкой имён файлов в OEM кодировке. Поддержка имён файлов в Unicode присутствует, однако требует изменения включаемого файла и пересборки библиотеки.
В большинстве случаев, libio следует прототипам функций POSIX. Для каждой функции, где это возможно, указан её POSIX эквивалент.
Функции (перебор файлов)
file_find_first
Найти первый файл с соответствующими атрибутами и маской в указанной директории.
Прототип:
- proc file.find_first _dir, _mask, _attr
Агрументы:
- _dir → asciiz
- директория, в которой нужно производить поиск
- _mask → asciiz
- маска файла, с использованием шаблонных символов
- _attr → dword
- маска атрибутов файла (комбинация констант FA_*)
Результат:
- eax → FileInfo*
- 0 (ошибка) / указатель на структуру с информацией о найденном файле (используется как дескриптор поиска)
file_find_next
Найти следующий файл, соответствующий критериям.
Прототип:
- proc file.find_next _findd
Аргументы:
- _findd → FileInfo*
- дескриптор поиска (см. file_find_first)
Результат:
- eax → FileInfo*
- 0 (ошибка) / указатель на структуру с информацией о найденном файле (используется как дескриптор поиска)
file_find_close
Закрыть дескриптор поиска и освободить память.
Прототип:
- proc file.find_close _findd
Аргументы:
- _findd → FileInfo*
- дескриптор поиска (см. 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>