Libs-dev/libio/ru: Difference between revisions
Sweetbread (talk | contribs) m (→Константы) |
Sweetbread (talk | contribs) m (Reverted edits by Sweetbread (talk) to last revision by Leency) Tag: Rollback |
||
Line 274: | Line 274: | ||
::разрещить параллельный доступ в файлу, используя разные дескрипторы (не реализовано) | ::разрещить параллельный доступ в файлу, используя разные дескрипторы (не реализовано) | ||
:<tt>O_TEXT</tt> | :<tt>O_TEXT</tt> | ||
::заменять символы | ::заменять символы конфа строки на LF (замещает O_BINARY, не реализовано) | ||
==Исходное место перемещения по файлу== | ==Исходное место перемещения по файлу== |
Revision as of 15:07, 16 January 2023
В настоящий момент, 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
Получить расширенную информацию об ошибке. Увы, функция пока не существует.
Константы
Режим открытия файла
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 может выглядеть так (для сравнения):
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);
}