BlockRead — Процедура Delphi


BlockRead — Процедура Delphi

Автор: Dennis Passmore

Следующий код демонстрирует использование нетипизированного входного файла для блочного чтения (blockread) текстового файла, сканирование входного буфера в поисках любого символа и их замены на символы перевода строки и возврата каретки. Поскольку код использует входные и выходные буфера размером 16к, то получаемая скорость весьма приемлема.

Примечание: В процессе обработки, если длина строки выходного файла превышает 255 символов и вы хотите прочесть ее с помощью ReadLn, то просто используйте в запросе ReadLn несколько строк, например так:

Так можно прочесть вплоть до 510 символьных строк с 1-й по 255 символ в string1 и остальное в string2;

BlockRead — Процедура Delphi

Здрасте всем! Есть следующий код:

reset(f,1);
size:=filesize(f);
closefile(f);
setlength(buf,size);
reset(f,size);
blockread(f,buf,1);
closefile(f);

Синтаксически вроде првильный. НО! после его выполнения массив buf не то что пустой, а имеет нулевую длину! :( Соответственно, любое обращение к нему влечёт EAccessViolation. В чём дело? Юзаю Delphi 6 Update Pack 2, возможности поставить семёрку нет — комп каменного века.

reset(f,1);
size:=filesize(f);
closefile(f);
setlength(buf,size);
reset(f,size);
blockread(f,buf [0],1);
closefile(f);

Ты на размер записи в reset посмотри, а потом пиши.

Кстати, вариант

reset(f,1);
size:=filesize(f);
setlength(buf,size);
blockread(f,buf,size);
closefile(f);

возвращает точно такой же результат, т.е. нулевой массив. :(

Тебе дали абсолютно верный совет, подходяший как для случая динамического массива, так и для статического с нумерацией с нуля. Обдумай его хорошо. Потом сдлай работу над ошибками.

Как думаешь в buf в вызове это @buf или @buf[0], учитывая что параметр объявлен ка . var Buf; .

>icWasya
Прошу прощения, сразу после отправки того сообщения я раскаялся, но как его отредактировать не нашёл. Извиняюсь.

Всем:
Как это сделать по-другому я знаю. НО! мне хотелось бы просто ПОНЯТЬ, почему мои примеры не работают? Я, кстати, нашёл в книге, что этот код не работает в D4 из-за неточностей в Blockread/Write, но что это исправленно в 5 и 6.

это все враки, не верь этому, авторы (или переводчики) отнюдь не мастера.
кто то уже жаловался по этому поводу.

а не работают потому что
BlockRead BlockWrite
работают не с самой переменной, а с ее адресом
ты передаешь в BlockRead/Write не тот адрес
Buf (дин массив) — это область размером в 4 байта (в Win32) представляющая собой указатель, в эту область ты и предлагаешь записать, но записывать надо не в нее, а туда куда она указывает.
тоесть передавая Buf[Low(Buf)] мы передаем в BlockRead/Write адрес начального элемента в массиве, куда благополучно все пишется.

Кстати блокреад наскольо я знаю в паскале работал только с записями до 64 кило. В дельфи это ограничение имхо тоже есть. Так что ещё размер надо учесть.

Люди, простите меня!
У меня, наверное, только сейчас голова начала работать. Мне с самого начала дали правильный совет, а я, ввиду своих ограниченных возможностей, его не понял. Простите все!

Илон Маск рекомендует:  Разворачивающееся окно.


> Snap © (25.04.03 20:59)

в d5 и d6, BlockRead/Write, прекрасно работает с размером и превышающим 64к
в версиях ниже не в курсе

Последнее сообщение я написал ещё не читая объяснения Palladin»а, но всё равно спасибо.

Pascal-Паскаль

Процедура BlockRead Pascal-Паскаль

  • Скачено бесплатно: 6843
  • Куплено: 414
  • Pascal-Паскаль->B->Процедура BlockRead Pascal-Паскаль

Процедура BlockRead Pascal-Паскаль

Описание

BlockRead — Считывает одну или большее количество записей из файла в переменную.

Объявление: Procedure BlockRead(Var F : File; Var Buf; Count : Word [; Var Result : Word]);
Режим: Windows, Real, Protected

Где:
F — нетипизированная файловая переменная
Buf — любая переменная
Count — выражение типа Word
Result — переменная типа Word


Замечания:

Процедура BlockRead считывает Count или меньшее количество записей из файла F в блок памяти, начинающийся с первого байта, занятого переменной Buf. Реальное количество прочитанных записей (меньшее или равное Count) возвращается в необязательном параметре Result. Если параметр Result не определен, то в случае, когда количество прочитанных записей не равно параметру Count, происходит ошибка ввода/вывода.

Весь считанный блок занимает максимум Count * RecSize байт, где RecSize — размер записи, определяемый при открытии файла (или 128 байт, если размер записи не был определен). Если Count * RecSize больше, чем 64Кб, то происходит ошибка.

Параметр Result является необязательным. Если весь запрошенный блок был считан, то Result будет равно Count. Иначе, в случае, если Result меньше, чем Count, то конец файла был достигнут прежде, чем было завершено считывание блока. В таком случае, если параметр RecSize был больше 1, то Result вернет количество целиком считанных записей.

Указатель текущей позиции файла перемещается на количество записей, равное значению параметра Result.

В режиме <$I->функция IOResult вернет нуль, если операция была успешной, иначе, она вернет отличный от нуля код ошибки.

Ограничения:

Файл должен быть открыт.

Пример программы для процедур BlockRead и BlockWrite

Программирование

Исходники Pascal (127)

Справочник

Справочник по паскалю: директивы, функции, процедуры, операторы и модули по алфавиту

BlockRead — Процедура Delphi

The file must have been assigned using AssignFile and opened with Reset.

The Reset routine by default will open the file with a record size of 128 bytes. This can be overriden in this routine to a value more useful to yourself (see example).

Data is written to the Buffer (normally a string or byte array) from the file. If the recordSize is 10 bytes, and RecordCount is 3, then 3 x 10 byte records are written, with 30 bytes taken from the file to do this.

Не пойму как работает BlockRead

Не могу понять как именно считывает BlockRead и что происходит с массивами там?

Типичная ошибка при работе с динамическими массивами

Посмотри, что в момент BlockRead происходит с Buf1, Enc1, OutCount, InCounter итд.

Смотрел, после этого Buf1 сперва отображает все 0, через строчку Inaccessible type.

Или можно войти внутрь этой процедуры?

Мне один умный человек очень советовал забыть про BlockRead и BlockWrite и использовать виндовский FileRead и FileWrite.

BlockRead и BlockWrite динамического массива

Я пытаюсь организовать сохранение и загрузку данных изменяется в размерах. Таким образом, сохранить файл нужно хранить несколько (неизвестно, и каждый раз, когда другое число) динамических массивов.

Илон Маск рекомендует:  PHP+Excel быстро генерируем XLS файлы

Ошибка появляется в этом MCVE:

Этот код приводит к ошибке I / O 998. Я пытался объявить тип TDoubleArray = array of Double; и передать в ari качестве параметра в BlockRead. Я также пытался , SetLength(ari, Count) прежде чем я называю BlockRead без какого — либо успеха.

Ответ на этот вопрос не помог мне. Код читает Count правильно , но поднимается исключение при загрузке массива. Что я делаю не так?

Вы должны установить размер блока в / Сброс команд Перепишите:

RecSize является необязательным выражение, которое может быть определено только, если F является нетипизированная файл. Если F является нетипизированной файл, RecSize определяет размер записи, которые будут использоваться в передаче данных. Если RecSize опущен, размер записи по умолчанию 128 байт предполагается.

Это означает, что чтение данных будет переполнение выделенного буфера, следовательно, ошибки ввода / вывода из системы.


Предупреждение : Это старый метод , который особенно опасен для использования из — за бестиповой параметр Buf, что приводит к потенциальной коррупции памяти. Размер записи используется BlockRead и BlockWrite регулируется с помощью дополнительного 2 — го параметра для сброса или Перепишите вызов , который был использован для открытия файла записываемого. Предпочтительно использовать потоки в своих приложениях. Например, процедура пользователя с участием потока может использовать как TMemoryStreams и TFileStreams , вместо того , чтобы быть ограничены использованием файлов , как с этими старыми рутин.

В общем случае разница в скорости между BlockRead/Write и потоков незначительна. Для больших файлов, предпочтительным является буферный обработчик.

Существует отличный пример буферном файл обработчик потока от Давида: буферизация файлов (для более быстрого доступа к диску)

Как @ Ки / @ TomBrunberg отметила и то , что вы пробовали, вы должны также выделить длину ari динамического массива перед чтением данных.

BlockRead и текстовый файл

Delphi , Файловая система , Файлы

Автор: Dennis Passmore

Следующий код демонстрирует использование нетипизированного входного файла для блочного чтения (blockread) текстового файла, сканирование входного буфера в поисках любого символа и их замены на символы перевода строки и возврата каретки. Поскольку код использует входные и выходные буфера размером 16к, то получаемая скорость весьма приемлема.

Примечание: В процессе обработки, если длина строки выходного файла превышает 255 символов и вы хотите прочесть ее с помощью ReadLn, то просто используйте в запросе ReadLn несколько строк, например так:

Так можно прочесть вплоть до 510 символьных строк с 1-й по 255 символ в string1 и остальное в string2;

Статья BlockRead и текстовый файл раздела Файловая система Файлы может быть полезна для разработчиков на Delphi и FreePascal.

Комментарии и вопросы

Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.

Процедура BlockRead

Процедура BlockRead читает данные из нетипизированного файла в память. Синтаксис:

Процедура Blockread считывает записи из файла F. Количество записей указано в параметре Count. Процедура считывает столько записей, сколько указано в этом параметре (или меньше, если файл содержит меньшее количество записей).

Илон Маск рекомендует:  Расширение набора стандартных функций и классов borland delphi

Запись — это блок байтов. Размер этого блока указывается при вызове процедур Rewrite или Reset.

Прочитанные данные помещаются в буфер Buf. Размер этого буфера должен быть достаточным для того, чтобы в нём поместилось столько записей, сколько указано в параметре Count.

Процедура не может считывать неполные записи (то есть записи, размер которых меньше, чем указан при вызове процедур Rewrite или Reset).

Если указан параметр Result, то он содержит количество фактически прочитанных записей. Если параметр Result не указан и было прочитано меньше записей, чем указано в Count, то происходит ошибка времени выполнения. Этим поведением можно управлять с помощью переключателя <$I>.

В зависимости от состояния переключателя <$I>при наличии ошибки может возникнуть ошибка времени выполнения. В состоянии <$I->используйте функцию IOResult для проверки ошибок. Подробнее о директивах компилятора см. здесь.

Иллюстрированный самоучитель по Delphi 7 для профессионалов

Операции ввода/вывода

Рассмотрим теперь режим блочного ввода/вывода данных между файлом и областью адресного пространства (буфером). Этот режим отличается значительной скоростью передачи данных, причем скорость пропорциональна размеру одного передаваемого блока – чем больше блок, тем больше скорость.

Для реализации этого режима необходимо использовать только нетипизированные файловые переменные. Размер блока определяется в процедуре открытия файла (Reset, Rewrite). Непосредственно для выполнения операций используются процедуры BlockRead и BlockWrite.

Выполняет запись блока из файла в буфер. Параметр F ссылается на нетипизированную файловую переменную, связанную с нужным файлом.

Параметр Buf определяет любую переменную (число, строку, массив, структуру), в которую читаются байты из файла. Параметр Count содержит число считываемых блоков. Наконец, необязательный параметр AmtTransferred возвращает число реально считанных блоков.

При использовании блочного чтения или записи размер блока необходимо выбирать таким образом, чтобы он был кратен размеру одного значения того типа, который хранится в файле. Например, если в файле хранятся значения типа Double (8 байт), то размер блока может быть равен 8, 16, 24, 32 и т. д. Фрагмент исходного кода блочного чтения при этом выглядит следующим образом:

Как видно из примера, размер блока установлен в процедуре Reset и кратен размеру элемента массива DoubleArray, в который считываются данные. В переменной Transfered возвращается число считанных блоков. Если размер файла меньше заданного в процедуре BlockRead числа блоков, ошибка не возникает, а в переменной Transfered передается число реально считанных блоков.

Оставшиеся функции ввода/вывода, работающие с файловыми переменными, подробно описаны в табл. 9.1.

BlockRead

Read data from an untyped file into memory

Declaration

Source position: systemh.inc line 1193

Description

Blockread reads count or less records from file F . A record is a block of bytes with size specified by the Rewrite or Reset statement. The result is placed in Buffer , which must contain enough room for Count records. The function cannot read partial records. If Result is specified, it contains the number of records actually read. If Result isn’t specified, and less than Count records were read, a run-time error is generated. This behavior can be controlled by the <$I>switch.

Errors

Depending on the state of the <$I>switch, a runtime error can be generated if there is an error. In the <$I->state, use IOResult to check for errors.

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL