1. Пользуйтесь тегами кода. - [code] ... [/code] 2. Точно указывайте язык, название и версию компилятора (интерпретатора). 3. Название темы должно быть информативным. В описании темы указываем язык!!!
Мне очень не нравится скорость побайтового чтения - 3МБ файл читается больше секунды, когда дельфовый аналог на BlockRead считывает его моментально. Всё, что приходит в голову - открыть файл для типа byte, узнать размер, потом открыть файл для массива данного размера и считать за раз.
Byte_IO.Open(SF, Byte_IO.In_File, "test.txt"); declare S: Byte_IO.Count := Byte_IO.Size(SF); type Arr is array (1..S) of byte; type AArr is access Arr; package Arr_IO is new Ada.Direct_IO(Arr); F: Arr_IO.File_Type; A: AArr; begin A := new Arr; Byte_IO.Close(SF); Arr_IO.Open(F, Arr_IO.In_File, "test.txt"); Arr_IO.Read(F, A.all); Arr_IO.Close(F); end;
Но это выдаёт raised STORAGE_ERROR : EXCEPTION_STACK_OVERFLOW (даже после того, как я вместо заведения массива на стеке завёл указатель) Да и мало ли размер файла изменится между первым и вторым открытиями. И вообще много дёргать винт это плохо.
Последний вариант - через ВинАПИ, но мне неохота туда лезть.
ПС Настраиваемые пакеты во внутреннем блоке - это сильно. Реально круто, я про язык.
begin -- Открыл Ada.Streams.Stream_IO.Open(SFIn, Ada.Streams.Stream_IO.In_File, File_Name); -- Получил размер Buf_Size := Integer (Ada.Streams.Stream_IO.Size (SFIn)); -- Выделил память Buffer := new Byte_Buffer (1 .. Buf_Size);
-- Проверил, все ли нормально if Buf_Size /= Bytes_Read then Ada.Text_IO.Put_Line ("Something goes wrong ..."); end if; -- Закрыл Ada.Streams.Stream_IO.Close(SFIn); end Main;
Не дожидаясь вопроса, сразу объясню, что такое Is_Workaround_Possible. У компиляторов GNAT и ObjectAda есть некоторые проблемы со скоростью выполнения Read и Write в потоках. Так вот, если Stream_Element это и есть байт, и оба тестовых массива одинаково упакованы и одинаково выровнены - то можно значительно ускорить операции чтения/записи, работая напрямую с массивом Stream_Element-ов, наложенным на буфер (строка for SE_Buffer'Address use Buffer'Address этим занимается). Если же нет возможности работать с таким массивом - что ж поделаешь - приходится читать медленно в буфер, это действительно медленно: автор замерял, говорит о 50-кратном замедлении в среднем. Если надо, кстати, есть и BlockWrite для стримов...