Форум: "Начинающим";
Текущий архив: 2010.12.12;
Скачать: [xml.tar.bz2];
ВнизПроблемы с записью/чтением типизированного файла Найти похожие ветки
← →
khrenkov © (2010-09-20 14:29) [0]Здравствуйте.
Необходимо, чтобы программа делала следующее (последовательно):
1. при нажатии кнопки ConversBtn обрабатывается выбранный файл *.CSV и его содержимое заносится в массив структур.
2. при нажатии кнопки SaveBtn файл, заполненный массивом структур записывается в файл *.SCDA.
3. при нажатии кнопки OpenBtn должен загружаться выбранный файл *.SCDA и в соответствии с его содержимым должны строиться графики.
Так же необходимо, чтобы п.3 выполнялся "самостоятельно", т.е. чтобы была возможность открыть сохраненный ранее файл *.SCDA.
Проблема:
При запуске приложения и выполнении п. 3 без п.1,2, т.е. при открытии ранее сохраненного файла *.SCDA загружается файл, значения полей структур в котором заполнены "плохими" значениями: нулями, очень маленькими значениями или Nan.
Примечание:
Если запустить приложение и выполнить п.1 и п.2, а в п.3 выбрать тот же файл, что был сохранен в п.2(предположим xxx.SCDA), то все строится и все функционирует.
Если же перезапустить приложение и выполняя п.3 выбрать файл xxx.SCDA, то загружаются некорректные данные.
Предположения:
Либо не правильно пишу в файл
Либо не правильно читаю файл
Кто чем может помочь?
TDataRecord = class(TObject)
private
FChan1: Single;
FChan2: Single;
FChan3: Single;
FChan4: Single;
FChan5: Single;
FChan6: Single;
FChan7: Single;
FDate: Double;
FDateTime: Double;
FTime: Double;
public
property Chan1: Single read FChan1 write FChan1;
.........
property Chan7: Single read FChan7 write FChan7;
property Date: Double read FDate write FDate;
property DateTime: Double read FDateTime write FDateTime;
property Time: Double read FTime write FTime;
{ Public declarations }
end;
TDataField = array of TDataRecord;
var
MainForm: TMainForm;
DataField1: TDataField;
Data: TDataField;
implementation
{$R *.dfm}
function TMainForm.ChangeSeparator(var StrTemp: string): string;
begin
StrTemp := StringReplace(StrTemp, ",", Decimalseparator,[rfReplaceAll]);
StrTemp := StringReplace(StrTemp, ".", Decimalseparator,[rfReplaceAll]);
end;
function TMainForm.BRKCheck(var StrTemp: string): string;
begin
if StrTemp = "BRK" then
StrTemp := "0";
end;
procedure TMainForm.ChanSwitcherClick(Sender: TObject);
var
I: Longint;
begin
............
end;
procedure TMainForm.ConversBtnClick(Sender: TObject);
var
OD: TOpenDialog;
Excel: Variant;
I, J, DocSize: Longint;
TempStr: string;
StopFlag: Boolean;
const
STRNUMBER: Longint = 20;
ROWNUMBER: Longint = 9;
begin
OD := TOpenDialog.Create(nil);
try
OD.Filter := "Файлы CSV|*.CSV";
OD.InitialDir := "C:\Program Files\Borland\Delphi7\Projects\Stove";
if OD.Execute then
begin
DataField1 := nil;
DocSize := 1;
StopFlag := true;
Excel := CreateOleObject("Excel.Application");
Excel.Workbooks.Open[OD.FileName];
while StopFlag do
begin
TempStr := Excel.Range["A" + IntToStr(DocSize)];
if TempStr = "" then
begin
StopFlag := false;
DocSize := DocSize - 1;
Break;
end;
Inc(DocSize);
end;
SetLength(DataField1,(DocSize div 10));
try
for I := 1 to (DocSize div 10) do
begin
DataField1[I-1] := TDataRecord.Create;
for J := 1 to ROWNUMBER do
begin
case J of
1:
begin
TempStr := Excel.Range["A" + IntToStr(I * 10)];
ChangeSeparator(TempStr);
DataField1[I-1].Date := StrToDate(TempStr);
end;
.............
9:
begin
TempStr := Excel.Range["I" + IntToStr(I * 10)];
BRKCheck(TempStr);
ChangeSeparator(TempStr);
DataField1[I-1].FChan7 := RoundTo(StrToFloat(TempStr),-2);
end;
end;
end;
end;
finally
Excel.ActiveWorkbook.Close;
Excel.Application.Quit;
Excel := Unassigned;
end;
end;
finally
OD.Free;
end;
end;
procedure TMainForm.SaveBtnClick(Sender: TObject);
var
SD: TSaveDialog;
FileName: string;
FileForWrite: File of TDataRecord;
I: Longint;
begin
SD := TSaveDialog.Create(nil);
try
SD.Filter := "Файлы SCDA|*.SCDA";
SD.InitialDir := "C:\Program Files\Borland\Delphi7\Projects\Stove";
if SD.Execute then
begin
FileName := Concat(SD.FileName,".SCDA");
AssignFile(FileForWrite,FileName);
Rewrite(FileForWrite);
for I := 0 to Length(DataField1) - 1 do
Write(FileForWrite,DataField1[i]);
CloseFile(FileForWrite);
end
finally
SD.Free;
end;
end;
procedure TMainForm.OpenBtnClick(Sender: TObject);
var
DataFile: TDataRecord;
OD: TOpenDialog;
FileName: string;
FileForRead: File of TDataRecord;
I: Longint;
Size: Integer;
begin
Data := nil;
OD := TOpenDialog.Create(nil);
try
OD.Filter := "Файлы SCDA|*.SCDA";
OD.InitialDir := "C:\Program Files\Borland\Delphi7\Projects\Stove";
if OD.Execute then
begin
FileName := OD.FileName;
AssignFile(FileForRead,FileName);
Reset(FileForRead);
Size := FileSize(FileForRead);
SetLength(Data,Size);
for I := 0 to Size - 1 do
begin
Data[i] := TDataRecord.Create;
Read(FileForRead,Data[i]);
end;
CloseFile(FileForRead);
// Edit1.Text := FileName;
end
finally
OD.Free;
end;
end;
end.
← →
MBo © (2010-09-20 14:40) [1]Объекты таким образом записывать в файл нельзя - получается, что в файл пишется значение указателя, адрес объекта. При сохранении-загрузке в одной сессии адреса еще остаются действительными, если не было уничтожения объектов, перезаписи данных областей памяти. При новом запуске даже призрачного шанса на это нет.
Поэтому
← →
MBo © (2010-09-20 14:47) [2]Рано отправил.
В данном случае не видно причин, кроме формальной инкапсуляции, по которым данный объект не может быть простой записью (record), а записи сохранять-читать легко.
В общем же случае для объектов надо реализовывать механизм сохранения-восстановления (см. TPersistent, TComponent, DefineProperties)
← →
Anatoly Podgoretsky © (2010-09-20 14:59) [3]Вообще то у тебя нет типизированного файла.
TDataRecord это не запись. Хочешь работать с записями, сделай Record
← →
khrenkov © (2010-09-20 15:04) [4]MBo, вашу идею понял, спасибо. С записями работает =)
← →
khrenkov © (2010-09-20 15:07) [5]Anatoly Podgoretsky, согласен!
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.12.12;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.003 c