![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Нетипизированные файлы [D7, XP]
!_SM_! © (2006-06-20 21:00:00)Здраствуйте! Подскажите пожалуйста как правильно работать с нетипизированными файлами т.е. запись/чтение данных своего типа.
Измучился уже с этой бедой
Вот как я делаю:
что здесь не так?
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, RXSpin, ExtCtrls;
type TData = record //Мой тип данных
Str1, Str2, Str3: PChar; //Здесь бы лучше тип String но сним вообще непонятка
Val1, Val2: Integer;
B1, B2: Byte;
Val3, Val4: LongInt;
end;
type
TForm1 = class(TForm)
edit1: TLabeledEdit;
edval1: TRxSpinEdit;
edval2: TRxSpinEdit;
Label2: TLabel;
Label3: TLabel;
edval3: TRxSpinEdit;
edval4: TRxSpinEdit;
Label4: TLabel;
Label5: TLabel;
edit2: TLabeledEdit;
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
DT: TData;
FL: TStream;
FlNm: String;
Dir: String;
implementation
{$R *.dfm}
procedure SaveData;
var N: Integer;
begin
with Form1 do begin
DT.Str1:=PChar(edit1.Text);
DT.Str2:=PChar(edit2.Text);
DT.Val1:=edVal1.AsInteger;
DT.Val2:=edVal2.AsInteger;
DT.Val3:=edVal3.AsInteger;
DT.Val4:=edVal4.AsInteger;
Fl:=TFileStream.Create(FlNm, fmOpenWrite or fmCreate);
N:=StrLen(DT.Str1); //Здесь пробовал
Fl.WriteBuffer(N, SizeOf(LongInt)); //разные варианты.
Fl.WriteBuffer(DT.Str1^, N); //Этот более менее работает
N:=StrLen(DT.Str2); //Но тоже не правильно
Fl.WriteBuffer(N, SizeOf(LongInt));
Fl.WriteBuffer(DT.Str2^, N);
Fl.WriteBuffer(DT.Val1, SizeOf(LongInt));
Fl.WriteBuffer(DT.Val2, SizeOf(LongInt));
Fl.WriteBuffer(DT.Val3, SizeOf(LongInt));
Fl.WriteBuffer(DT.Val4, SizeOf(LongInt));
Fl.Free;
end;
end;
procedure LoadData;
var N: Integer;
begin
with Form1 do begin
Fl:=TFileStream.Create(FlNm, fmOpenRead);
Fl.ReadBuffer(N, SizeOf(LongInt)); //И здесь пробовал
Fl.ReadBuffer(DT.Str1^, N); //соответственно
Fl.ReadBuffer(N, SizeOf(LongInt)); //пробовал по разному
Fl.ReadBuffer(DT.Str2^, N);
Fl.ReadBuffer(DT.Val1, SizeOf(LongInt));
Fl.ReadBuffer(DT.Val2, SizeOf(LongInt));
Fl.ReadBuffer(DT.Val3, SizeOf(LongInt));
Fl.ReadBuffer(DT.Val4, SizeOf(LongInt));
edit1.Text:=DT.Str1;
edit2.Text:=DT.Str2;
edVal1.AsInteger:=DT.Val1;
edVal2.AsInteger:=DT.Val2;
edVal3.AsInteger:=DT.Val3;
edVal4.AsInteger:=DT.Val4;
Fl.Free;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
GetDir(0, Dir);
FlNm:=Dir+'\Data.dat';
//if FileExists(FlNm) then LoadData else SaveData; //Вот так можно делать или нет т.е. в OnCreate формы присваивать полям разных едитов значения (LoadData)?
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SaveData;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if FileExists(FlNm) then LoadData;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SaveData;
end;
end.
Вопрос наверное про файлы нираз ставился. Все перерыл, перепробовал - ничего не получаеться. Раньше с нетипизированными файлами не работал. Ответьте пожалуйста.
Спасибо.
!_SM_! (2006-06-21 12:10:00) [21]
> Lex_! © (21.06.06 05:14) [17]
С типизированными легче, понятно, но в том то и дело что надо с нетипизированными.
palva (2006-06-21 10:56:00) [22]> Подскажите тогда пожалуйста как мне лучше работать с типом...
Record можно записать файл и прочитать из файла, здесь, как я понял у вас трудностей нет. Но дело в том, что ваш record содержит указатели на другие данные (String и PChar занимают 4 байта и содержат только указатель на символьные данные). Конечно, вы хотите сохранить и эти данные тоже. В этом случае я не вижу другого выхода как аккуратно написать самому программу чтения и программу записи, продумать формат хранения такой записи. То есть вам придется для каждой строки записать в файл сначала ее длину, а затем символы. Тогда при чтении файла вы сможете восстановить первоначальный вид строки. Может быть, для этого есть какие-то стандартные средства, но я их не знаю.
MBo (2006-06-21 07:59:00) [23]http://www.delphikingdom.ru/lyceum/seminar.asp?ID=2
Lex_! (2006-06-21 05:16:00) [24]
> Кстати. RxLib заменять не нужно. Эта библитотека одна из
> самых лучших библиотек для Дельфи. Она у меня установлена
> уже давно.
Jedi Visual Сomponent Library (JVCL) помоему лучше ... :)
Lex_! (2006-06-21 05:14:00) [25]При этом файл типизированный....
Lex_! (2006-06-21 05:13:00) [26]
var f: file of TData;
td:TData;
....
begin
....
Read(f,td);
Write(f,td);
...
end;
!_SM_! (2006-06-21 04:33:00) [27]
> Германн © (21.06.06 04:19) [13]
Я хоть посмотрю как это делаеться... Если ты конечно здесь напишешь проверенные тобой процедуры или функции.....
!_SM_! (2006-06-21 04:23:00) [28]Могу на мыло выслать весь этот пример. Тем более Rx установлен...
И у меня она установлена давно.
Германн (2006-06-21 04:19:00) [29]И ещё. Ну напишу я тестовый проект. И у меня всё будет как-то работать или не работать. Где гарантия, что у тебя тоже самое?
Германн (2006-06-21 04:08:00) [30]
> !_SM_! (21.06.06 03:55) [11]
Т.е. тестовый проект должен написАть я! А мне это нужно?
Кстати. RxLib заменять не нужно. Эта библитотека одна из самых лучших библиотек для Дельфи. Она у меня установлена уже давно.
!_SM_! (2006-06-21 03:55:00) [31]
> потому что без dfm, нет смысла пробовать.
Здесь собственно пробовать нужно 2 процедуры LoadData и SaveData
а значения брать/отоброжать в любых доступных компанентах
Моя форма (файл dfm) содержит два Edita и 4 TRxSpinEdita
Первые 2 стандартные Едиты Остальные из RXLib можно заменить чемнить похожим. И две кнопки. Вызывающие при нажатии соответственно одну из процедур. В процедуре записи - Числа можно генерить случайно т.е.
DT.Val1:=Random(100);
при чтении можно вообще их опустить просто, ну, пусть в файле Data.dat будут присутствовать. Вообщем с формой я думаю ничего сложного нет.
Германн (2006-06-21 03:39:00) [32]
> С прошедшим днем рождения!
Спасибо.
> Если есть возможность попробуйте код который я написалтам
> почему-то при чтении обрезаются строки
Увы нет такой возможности! И не столько потому что у меня нет времени на пробу, сколько потому что без dfm, нет смысла пробовать. Т.е. пробовать в рамках Дельфи можно лишь, в данном случае, проект. Либо процедуру/функцию не имеющую связи с какой-либо формой.
!_SM_! (2006-06-21 03:00:00) [33]С прошедшим днем рождения!
!_SM_! (2006-06-21 02:55:00) [34]
> Германн © (21.06.06 02:23) [7]
> 1. А тип ShortString чем не подходит?
В том то и дело что хочется научится с длинными строками
или например с такими данными как Arr = array of TData
т.е. динамически изменяемыми
> Логичнее писАть ReadBuffer(N, SizeOf(N));
Пробывал и так разницы нет.
Если есть возможность попробуйте код который я написал
там почему-то при чтении обрезаются строки
3 Блин, а я чет и забыл про выделение памяти просто сначала я пробовал
со Stringo'м (типом) вместо PChar. Башню рвет уже. Пример выше хоть и криво но работает что-то пишет в файл - Блокнотом смотришь вроде то че надо там есть (имею ввиду строки) - читаешь - тут херь какая-то.
Никак не въеду как правильно делать
Германн (2006-06-21 02:23:00) [35]1. А тип ShortString чем не подходит?
2. Придирка, но всё же. Зачем писАть ReadBuffer(N, SizeOf(LongInt));?
Логичнее писАть ReadBuffer(N, SizeOf(N));
3. В целом, принцип записи/чтения длинных строк правильный. Сначала пишется/читается длина, затем сама строка. Вот токмо где выделение памяти под PChar в примере? (Для String - SetLength).
4. Могу быть не прав, но сам предпочитаю в подобных случаях вместо DT.Str1^ писАть DT.Str1[1].
!_SM_! (2006-06-21 01:54:00) [36]Подскажите тогда пожалуйста как мне лучше работать с типом
type TData = record //Мой тип данных
Str1, Str2, Str3: PChar; //Здесь бы лучше тип String но сним вообще непонятка
Val1, Val2: Integer;
B1, B2: Byte;
Val3, Val4: LongInt;
end;
Записывать в файл и читать из файла.
Здесь в "программе" я собственно привел пример что мне нужно
Пример НЕ РАБОЧИЙ. :(
Хотелось бы знать как надо правильно работать с файловыми потоками.
palva (2006-06-20 22:41:00) [37]> как правильно работать с нетипизированными файлами
Насколько я вижу, вы в программе вообще не работаете с нетипизированными файлами. У вас файловые потоки.
А нетипизированный файл - это такой тип с именем File. То есть вы где-то должны объявить переменную:
var f: File;
> в частности со строками.
Строки не являются частным случаем нетипизированных файлов. Строки это отдельная группа типов.
!_SM_! (2006-06-20 21:27:00) [38]Переменная кстати есть.
DT: TData;
Так в том то и дело не надо целиком...
ну или например часть ее считать и/или записать.
Собственно вопрос - как правильно работать с нетипизированными файлами
в частности со строками.
Спасибо.
Alien1769 (2006-06-20 21:22:00) [39]
> т.е есть тип
Так создать надобно переменную этого типа,
далее читать/писать одну переменнуюа, потом можно ее уже юзать!
!_SM_! (2006-06-20 21:16:00) [40]Извиняюсь если неправильно выразился.
т.е есть тип (см. выше по коду)
егошним полям присваиваются значения
записываються в файл потом эти значения нужно считать и присвоить
полям моего типа. Вот.