Author Archive

19
Июл

LUA.Бинарные файлы(3)

Posted by: Kamynin   in QLUA

В данной заметке размещена библиотека,
которая позволяет работать с двоичными файлами.

Немного теории

   32 разрядные процессоры работают с данными, которые представлены в виде, вещественное число — это 8 байт, целое число — 4 байта (32 разряда),
а строка — это на каждый символ -один байт, в конце строки ноль (кодировка ACIIZ) или длина строки в начале.


 В луа есть два вида данных — вещественные числа и строки. Целых чисел нет — они вещественные.


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


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

Вещественное число имеет точность 15 десятичных цифр плюс еще порядок 5 цифр.
Таким образом, если выводим максимальное вещественное число, то в файле целые числа могут занять до 15 байт, а вещественные до 20 байт. В сравнении со стандарным способом это примерно в три раза больше места занимает.

Кроме того, когда мы пишем в файл данные оператором file:write(x), то луа проверяет тип и преобразует в строку по формату для записи в файл .
Так вот, я написал и выложил модуль для луа для работы с двоичными файлами.
Т е в эти файлы вещественное число пишется в 8 байт, целое в 4 байта, а строки либо в формате ASCIIZ либо в формате с явной длиной.
В результате получилось, что запись в файл чисел происходит в 4-6 раз быстрее. 
Кроме того, файлы с числами имеют упорядоченную структуру, поэтому можно в луа осуществлять произвольный доступ к данным в файле. 
Т е использовать файлы как массивы неограниченного размера.
 

В библиотеке реализованы следующие функции:

open(имя,режим) — открыть файл
close()                             -закрыть файл
getf(x)                             -записать вещественное число
x=setf()                          —прочитать вещественное число
geti (x)                            — записать  целое число
x=seti (x)                      — прочитать целое число
gets(S)                            -записать строку
S=sets()                         -прочитать строку
getsn(S)                         -записать строку
S=setsn()                      -прочитать строку
pos=getpos()              -получить текущую позицию
setpos(pos)                  -yстановить текущую позицию
seek(off,org)               -переместить текущую позицию
flush ()                            -сбросить данные на диск
lenf ()                                — получить длину файла в байтах

Пример теста:

d1=»C:/»; — устройство
package.cpath =d1..»dll_lib/?.dll;»..package.cpath — путь к библиотеке
—————-
require «nklib» —— загрузка библиотеки

x=1000;
N=100000000;
—————————————-запись в текстовый файл
local nfile2=»C:/NK/testbin.txt»;
local file=io.open(nfile2,»wt»);
local t1=os.clock ()
local k=1; while (N>k) do file:write(tonumber(x)); k=k+1; end
local t2=os.clock ()
t3=os.difftime (t2,t1);
file:close();
print(t3);

—————————————-запись в двоичный файл
nfile=»C:/NK/testbin.bin»;
nklib.open(nfile,»w+»);
local t1=os.clock ()
local k=1; while (N>k) do nklib.seti(x); k=k+1; end
local t2=os.clock ()
t3=os.difftime (t2,t1);
nklib.close();
print(t3);

———————————

Работа с двоичными файлами примерно в 4-6 раз быстрее, чем с текстовыми.

Двоичные файлы можно использовать в качестве больших массивов с произвольным доступом.

Библиотеку можно взять здесь: NKlib