![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | 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); |
|
#3
|
|||
|
|||
|
Предполагается, что записи в типизированном файле имеют одинаковый размер (иначе, как позиционироваться на нужной записи по ее номеру?).
Следовательно, запись (record) должна быть определена строго. В данном случае, STRING - это не строгое определение. Лучше уточнить. Типа: Код:
Tinfo = record
name:string[100];
version:string[30];
lang:string[20];
typ: byte;
roz: boolean;
end; |
|
#4
|
||||
|
||||
|
файл-то НЕ типизированый
![]() Код:
var f: file; |
|
#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 символов и т.д.
|
|
#7
|
|||
|
|||
|
Это да. Тут не поспоришь.
Но тогда (может быть) стОит поиграть с форматом этого файла. Например, использовать коммуникативный стандарт ISO 2709. Или другой (с предопределенными разделителями полей). Хотя это может быть существенно сложнее. |
|
#8
|
||||
|
||||
|
Может быть. Я лично не люблю стандарты, и обычно сочиняю форматы файлов на ходу. Надо картинку? хорошо, пишем размеры и саму картинку. Надо базу данных для проекта? отлично, пишем кол-во записей, виды записей, их названия и сами записи.
Все в таком духе. Но это уже оффтоп. |
|
#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 для удобства |