![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() Доброго время суток
Помогите пожалуйста! не читает string из бинарного нетипизированного файла Код:
type Tinfo = record name:string; version:string; lang:string; typ: byte; roz: boolean; end; Код:
var Form1: TForm1; info: TInfo; запись: Код:
procedure TForm1.Button3Click(Sender: TObject); var f: file; i: byte; t: cardinal; asa: string; begin info.name:=Edit1.Text; info.version:= Edit2.Text; info.lang:= Edit3.Text; info.typ:=ComboBox2.ItemIndex; info.roz:=CheckBox1.Checked; if SaveDialog1.Execute then begin AssignFile(f, SaveDialog1.FileName); ReWrite(f, 1); BlockWrite(f,info.roz,1); //info t:=sizeof(info.name)*Length(info.name); BlockWrite(f,t,4); BlockWrite(f,info.name,t); closefile(f); end; end; чтение: Код:
procedure TForm1.Button2Click(Sender: TObject); var f: file; t: cardinal; s:string; begin if OpenDialog1.Execute then begin AssignFile(f, OpenDialog1.FileName); ReSet(f, 1); BlockRead(f,info.roz,1); //info BlockRead(f,t,4); BlockRead(f,s,t); Edit1.Text:=s; CloseFile(f); end; end; выдает ошибку "Accses violation at address ......" после Edit1.Text:=s; |
#2
|
||||
|
||||
![]() прикол в том, что в Дельфи String - это указатель на строку. И занимает он 4 байта.
А BlockRead'у пофигу - он копирует данные из файла в оперативку. Получается, что в String лежит какой-то левый адрес. При записи надо так: Код:
t:=sizeof(char)*Length(info.name); //CHAR в случае, если String, и AnsiChar для AnsiString BlockWrite(f,t,4); BlockWrite(f,pointer(info.name)^,t); При чтении соответственно примерно так: Код:
BlockRead(f,t,4); SetLength(s,t); BlockRead(f,pointer(s)^,t); jmp $ ; Happy End! The Cake Is A Lie. |
#3
|
|||
|
|||
![]() Предполагается, что записи в типизированном файле имеют одинаковый размер (иначе, как позиционироваться на нужной записи по ее номеру?).
Следовательно, запись (record) должна быть определена строго. В данном случае, STRING - это не строгое определение. Лучше уточнить. Типа: Код:
Tinfo = record name:string[100]; version:string[30]; lang:string[20]; typ: byte; roz: boolean; end; |
#4
|
||||
|
||||
![]() файл-то НЕ типизированый
![]() Код:
var f: file; jmp $ ; Happy End! The Cake Is A Lie. |
#5
|
|||
|
|||
![]() Да.
Но если в нем хранить инфу из RECORD, то логично с ним работать, как с типизированным. Типа : Код:
//======= Запись (дополнение в конец) ======== Var MyRec: Tinfo; F : file of Tinfo; Ok99 : boolean; begin AssignFile(F,SaveDialog1.FileName); {$I-} Rewrite(F) {$I+}; Ok99:=(IoResult=0); if Ok99 then begin TRY {$I-} write(F,MyRec) {$I+}; Ok99:=(IoResult=0); if not Ok99 then begin ShowMessage('Ошибка записи в файл'); end; FINALLY {$I-} CloseFile(F) {$I+}; Ok99:=(IoResult=0); END; end else begin ShowMessage('Ошибка открытия файла на запись'); end; end; //=================================== //======= Чтение записи номер 0 ======== Var MyRec: Tinfo; F : file of Tinfo; Ok99 : boolean; begin AssignFile(F,SaveDialog1.FileName); {$I-} Reset(F) {$I+}; Ok99:=(IoResult=0); if Ok99 then begin TRY {$I-} seek(F,0) {$I+}; Ok99:=(IoResult=0); if Ok99 then begin {$I-} read(F,MyRec) {$I+}; Ok99:=(IoResult=0); if not Ok99 then begin ShowMessage('Ошибка чтения из файла'); end; end else begin ShowMessage('Ошибка позиционирования в файле'); end; FINALLY {$I-} CloseFile(F) {$I+}; Ok99:=(IoResult=0); END; end else begin ShowMessage('Ошибка открытия файла на чтение'); end; end; //=================================== Это проще и надежнее. |
#6
|
||||
|
||||
![]() Кому как. По надежности - одинаково. только вот в типизированном файле можно будет хранить строку до 100 символов (если так объявить), и, более того, строка даже в 1 символ будет занимать 100 байт. А с НЕтипизированным можно делать че угодно - дописать в начале заголовок файла, в конце напихать полезную инфу и копирайты, хранить строки от 1 символа до 2^32 символов и т.д.
jmp $ ; Happy End! The Cake Is A Lie. |
#7
|
|||
|
|||
![]() Это да. Тут не поспоришь.
Но тогда (может быть) стОит поиграть с форматом этого файла. Например, использовать коммуникативный стандарт ISO 2709. Или другой (с предопределенными разделителями полей). Хотя это может быть существенно сложнее. |
#8
|
||||
|
||||
![]() Может быть. Я лично не люблю стандарты, и обычно сочиняю форматы файлов на ходу. Надо картинку? хорошо, пишем размеры и саму картинку. Надо базу данных для проекта? отлично, пишем кол-во записей, виды записей, их названия и сами записи.
Все в таком духе. Но это уже оффтоп. jmp $ ; Happy End! The Cake Is A Lie. |
#9
|
|||
|
|||
![]() Я с таким сталкивался, тип string - тип переменной длины, т.е. когда программа читает strinbg из файла она не знает, какую длину её читать.
Можно сделать так: string[255] - строка из 255 символов |
#10
|
|||
|
|||
![]() Bargest
огромное спасибо работает только там нужно Код:
BlockRead(f,t,4); SetLength(s,t div 2); BlockRead(f,pointer(s)^,t); в Delphi 2010 кодировка Unicode насколько я понял.... Последний раз редактировалось crea, 25.11.2010 в 00:58. |
#11
|
|||
|
|||
![]() типизированный не подходит но всеравно спасибо)
Record для удобства |