Форум: "Начинающим";
Текущий архив: 2006.03.12;
Скачать: [xml.tar.bz2];
ВнизКак лучше хранить координаты точек в файле? Найти похожие ветки
← →
Дмитрий_177 (2006-02-21 21:19) [0]Как лучше хранить координаты точек в файле? У меня есть много точек с координатами (x, y), как лучше всего сохранять их в файле?
← →
Zeqfreed © (2006-02-21 21:31) [1]Полагаю, двойками целочисленных значений фиксированного размера.
← →
Дмитрий_177 (2006-02-21 21:39) [2]а как это? я сначала думал так: два текстовых вайла... в одном x-ы, в другом y-ки.. и первая строка одного и второго файла и будут координаты... но тут 2-а файла и строку переводить из string в integer... это на скорости мне кажется скажется...
← →
Джо © (2006-02-21 21:45) [3]Можно в типизированных файлах (file of TPoint), можно не типизированных (file). Да как угодно можно.
← →
Джо © (2006-02-21 21:46) [4]У тебя точки в какой структуре данных хранятся?
← →
Дмитрий_177 (2006-02-21 21:49) [5]еще пока никак.... я их из bmp файла считываю... т.е. определенным цветом точки... чтобы каждый раз не тратить время напоиск этих точек определенным каким-то цветом, я хочу их как-то сохранить...
← →
Дмитрий_177 (2006-02-21 22:08) [6]А ктонибудь знает модуль DataFile? я им пользуюсь и сохраняю все... это как ini-файлы только лучше
← →
Джо © (2006-02-21 22:29) [7]> [5] Дмитрий_177 (21.02.06 21:49)
> еще пока никак.... я их из bmp файла считываю
Куда?
← →
Zeqfreed © (2006-02-21 22:35) [8]
type
TDynPointsArray = array of TPoint;
. . .
function SavePoints(const Filename : String; const Points : array of TPoint) : Boolean;
type
TPointsArray = array[0..0] of TPoint;
var
f, i : Integer;
buf : Pointer;
begin
Result := false;
f := FileCreate(Filename, fmCreate);
if (f = -1) then Exit;
GetMem(buf, SizeOf(TPoint) * Length(Points));
try
for i := Low(Points) to High(Points) do
TPointsArray(buf^)[i] := Points[i];
FileWrite(f, buf^, SizeOf(TPoint) * Length(Points));
Result := true;
finally
FreeMem(buf);
end;
try
finally
FileClose(f);
end;
end;
function ReadPoints(const Filename : String; var Points : TDynPointsArray) : Boolean;
type
TPointsArray = array[0..0] of TPoint;
var
f, i, size : Integer;
buf : Pointer;
begin
Result := false;
f := FileOpen(Filename, fmOpenRead or fmShareDenyWrite);
if (f = -1) then Exit;
try
size := GetFileSize(f, nil);
GetMem(buf, size);
try
if FileRead(f, buf^, size) = size then begin
SetLength(Points, size div SizeOf(TPoint) + 1);
for i := 0 to (size div SizeOf(TPoint)) do
Points[i] := TPointsArray(buf^)[i];
Result := true;
end;
finally
FreeMem(buf);
end;
finally
FileClose(f);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
a, b : TDynPointsArray;
i : Integer;
s : String;
begin
Randomize();
SetLength(a, 2);
for i := Low(a) to High(a) do begin
a[i].X := Random(High(Integer));
a[i].Y := Random(High(Integer));
end;
if SavePoints("C:\1.points", a) then
if ReadPoints("C:\1.points", b) then begin
for i := Low(a) to High(a) do begin
s := s + Format("%d, %d"#13#10, [b[i].X, b[i].Y]);
end;
ShowMessage(s);
end;
end;
← →
Джо © (2006-02-21 23:13) [9]Такое вроде по-проще будет ;)
unit PointsUtils;
interface
uses Windows, SysUtils, Classes;
type
TPoints = class
private
FList: TList;
procedure SetItems(Index: Integer; const Value: TPoint);
function GetItems(Index: Integer): TPoint;
function GetCount: Integer;
public
constructor Create();
destructor Destroy; override;
function Add (X,Y: Integer): Integer; overload;
function Add (APoint: TPoint): Integer; overload;
property Count: Integer read GetCount;
property Items[Index: Integer]: TPoint read GetItems write SetItems; default;
procedure Clear;
procedure SaveToStream (AStream: TStream);
procedure SaveToFile (AFileName: string);
procedure LoadFromStream (AStream: TStream);
procedure LoadFromFile (AFileName: string);
end;
implementation
type
PPoint = ^TPoint;
{ TPoints }
function TPoints.Add(X, Y: Integer): Integer;
var
Pt: TPoint;
begin
Pt.X := X;
Pt.Y := Y;
Result := Add (Pt)
end;
function TPoints.Add(APoint: TPoint): Integer;
var
NewPt: PPoint;
begin
GetMem (NewPt,SizeOf(TPoint));
NewPt^ := APoint;
Result := FList.Add(NewPt)
end;
procedure TPoints.Clear;
var
I: Integer;
begin
for I := Count - 1 downto 0 do
FreeMem (FList[I]);
FList.Clear;
end;
constructor TPoints.Create;
begin
inherited;
FList := TList.Create;
end;
destructor TPoints.Destroy;
begin
Clear;
FList.Free;
inherited;
end;
function TPoints.GetCount: Integer;
begin
Result := FList.Count
end;
function TPoints.GetItems(Index: Integer): TPoint;
begin
Result := PPoint(FList[Index])^
end;
procedure TPoints.LoadFromFile(AFileName: string);
var
Fs: TFileStream;
begin
Fs := TFileStream.Create(AFileName,fmOpenRead);
try
LoadFromStream(Fs);
finally
Fs.Free;
end;
end;
procedure TPoints.LoadFromStream(AStream: TStream);
var
I,
Cnt: Integer;
Pt: TPoint;
begin
Clear;
AStream.Read(Cnt,SizeOf(Cnt));
for I := 0 to Cnt-1 do
begin
AStream.Read(Pt,SizeOf(Pt));
Add (Pt)
end;
end;
procedure TPoints.SaveToFile(AFileName: string);
var
Fs: TFileStream;
begin
Fs := TFileStream.Create(AFileName,fmCreate);
try
SaveToStream(Fs);
finally
Fs.Free;
end;
end;
procedure TPoints.SaveToStream(AStream: TStream);
var
I: Integer;
Pt: TPoint;
Cnt: Integer;
begin
// количество точек
Cnt := Count;
AStream.Write(Cnt,SizeOf(Cnt));
// сами точки
for I := 0 to Count - 1 do
begin
Pt := Self[I];
AStream.Write(Pt,SizeOf(TPoint));
end;
end;
procedure TPoints.SetItems(Index: Integer; const Value: TPoint);
begin
PPoint(FList[Index])^ := Value
end;
end.
Пример использования:
---------------------
procedure TForm18.Button1Click(Sender: TObject);
var
APoints: TPoints;
I: Integer;
begin
APoints := TPoints.Create;
try
APoints.Add(10,20);
APoints.Add(30,40);
APoints.Add(50,60);
APoints.SaveToFile("d:\points.dat");
APoints.Clear;
APoints.LoadFromFile ("d:\points.dat");
for I := 0 to APoints.Count - 1 do
ShowMessageFmt("%d,%d",[APoints[I].X,APoints[I].Y]);
finally
APoints.Free;
end;
end;
← →
Zeqfreed © (2006-02-21 23:37) [10]
> Такое вроде по-проще будет ;)
Сложно сказать наверняка :)
Было бы больше пользы, конечно, если бы автор ещё свой вариант составил.
← →
Дмитрий_177 (2006-02-21 23:54) [11]Я вот разбираюсь... хочу написать еще две функции в DataFile, какраз для считывания точек... но что-то никак... если кто не знает могу скинуть модуль, мне он нравится )))
← →
Дмитрий_177 (2006-02-21 23:55) [12]в этих примерах при чтении из файла мы знаем что ф этом файле только точки... а вдруг там еще чтонибудь будет записано?
← →
Джо © (2006-02-22 00:01) [13]> [12] Дмитрий_177 (21.02.06 23:55)
> в этих примерах при чтении из файла мы знаем что ф этом
> файле только точки... а вдруг там еще чтонибудь будет записано?
Что значит "вдруг"?
← →
Дмитрий_177 (2006-02-22 00:11) [14]как в ini-файлах.. и строки и числа и др. т.е. не только точки...
← →
Дмитрий_177 (2006-02-22 00:12) [15]но повторюсь... функцией хотел бы сохранять несколько точек в одном параметре секции...
← →
Джо © (2006-02-22 00:19) [16]Смотри класс
TIniFile
и его методыWriteInteger
иReadInteger.
← →
Дмитрий_177 (2006-02-22 00:22) [17]да, но там же вроде как фиксированный размер типа Integer, а тут массив из TPointer, как мне узнать длинну массива или как-то там еще, чтобы прочитать его
← →
Джо © (2006-02-22 00:29) [18]> , как мне узнать длинну массива
High
← →
Дмитрий_177 (2006-02-22 00:36) [19]у меня что-то не получается (((
функции из DataFile для чтения и записи данных
function TDataFile.WriteData(Section, Ident: string; pBuf: Pointer; Count: Integer): Integer;
var
Hdr : IDataHeader;
P : Pointer;
begin
Delete(Section, Ident);
FFile.Seek(0, soFromEnd);
{ feel header }
Hdr.Id := DF_HEADER_IDENT;
StrPCopy(Hdr.Section, Section);
StrPCopy(Hdr.Ident, Ident);
Hdr.Size := Count;
{ xor }
EncryptBuf(@Hdr, SizeOf(IDataHeader));
{ write header }
Result := FFile.Write(Hdr, SizeOf(IDataHeader));
if( Result > -1 )then
begin
GetMem(P, Count);
try
Move(pBuf^, P^, Count);
{ xor data }
EncryptBuf(P, Count);
{ write data }
Result := FFile.Write(P^, Count);
finally
FreeMem(P, Count);
end;
end;
end;
function TDataFile.ReadData(Section, Ident: string; pBuf: Pointer): Integer;
var
Found : boolean;
Hdr : IDataHeader;
begin
Found := FindIdent(Section, Ident, @Hdr);
if( Found )then
begin
Result := FFile.Read(pBuf^, Hdr.Size);
DecryptBuf(pBuf, Hdr.Size);
end else
Result := -1;
end;
программа:
type
TDynPointsArray = array of TPoint;
procedure TForm1.Button1Click(Sender: TObject); // запись
var
a: TDynPointsArray;
i: integer;
begin
SetLength(a, 2);
for i := Low(a) to High(a) do
begin
a[i].X := Random(500);
a[i].Y := Random(500);
end;
with TDataFile.Create("C:\1.points") do
try
WriteData("1", "1", @a, SizeOf(TPoint) * Length(a));
finally
Free;
end;
end;
procedure TForm1.Button2Click(Sender: TObject); // чтение
var
Buf: array[0..1023]of Char;
a: TDynPointsArray;
i, Count: integer;
s: string;
begin
with TDataFile.Create("C:\1.points") do
try
Count := ReadData("1", "1", @Buf);
if (Count >= SizeOf(TPoint)) then
Move(Buf, a, SizeOf(TPoint));
finally
Free;
end;
for i := Low(a) to High(a) do
begin
s := s + IntToStr(a[i].X) + " " + IntToStr(a[i].Y) + " ";
end;
ShowMessage(s);
end;
← →
Дмитрий_177 (2006-02-22 15:37) [20]я наверно поздно вопрос задал и с появлением новых он затерялся...
← →
Дмитрий_177 (2006-02-24 23:42) [21]А можно ли такой массив перевести в поток? там есть функция WriteStream, сохраняющая поток...
← →
Дмитрий_177 (2006-02-24 23:43) [22]но потом обратно конечно... из потока в массив для чтения )))
← →
TStas © (2006-02-24 23:50) [23]Если координаты - TPoint, то FIle of TPOint Я, например, только TFIleStream"Ом и пользуюсь В нем замечательно храняться ЛЮБЫЕ структуры. Sz:=fs.Seek(0, soFromEnd) даст вам размер вашего файла в байтах, дальше, думаю, понятно
← →
Дмитрий_177 (2006-02-24 23:53) [24]TStas © вы не поняли... у меня в одном файле не только точки хранятся... но и числа там разные, и всякая другая информация...
← →
Zeqfreed © (2006-02-24 23:58) [25]23] TStas © (24.02.06 23:50)
> Sz:=fs.Seek(0, soFromEnd) даст вам размер вашего файла в
> байтах
Согласно справке, Seek изменит текущую позицию в потоковом ресурсе. А вот TFileStream.Size как раз вернет размер файла.
[24] Дмитрий_177 (24.02.06 23:53)
> у меня в одном файле не только точки хранятся... но и числа
> там разные, и всякая другая информация...
Нужно использовать нетипизированные файлы. А для хранения числовых данных использование текстовых файлов, а тем более каких-то ini-подобных оберток, как мне кажется, жутко неудобно.
← →
Джо © (2006-02-25 00:17) [26]> [24] Дмитрий_177 (24.02.06 23:53)
> у меня в одном файле не только точки
> хранятся... но и числа там разные, и всякая другая информация...
Тут уже советов надавали — море. На все случаи жизни. А ты все повторяешь одно и тоже, вероятно, не дав себе труда хотя бы понять то, что тебе писали.
← →
TStas © (2006-02-25 00:35) [27]А как раз понял, почему TFileStream и посоветовал У меня в нем хранилась элекктронная таблица, наподобие экселевской, с форматированием, текстом и формулой произвольной длинны, нй и координатами, конечно.
← →
Джо © (2006-02-25 00:38) [28]> [27] TStas © (25.02.06 00:35)
> А как раз понял, почему TFileStream и посоветовал
И правильно, кстати, посоветовал. :)
← →
Дмитрий_177 (2006-02-25 00:42) [29]а как мне перевести массив в поток? какой функцией? подскажите пожалуйста
← →
Дмитрий_177 (2006-02-25 00:43) [30]ну или не только массив... вообще любую переменную или класс... TStas © как вы перевели таблицу в поток?
← →
Джо © (2006-02-25 00:44) [31]>
>
> [29] Дмитрий_177 (25.02.06 00:42)
> а как мне перевести массив в поток? какой функцией? подскажите
> пожалуйста
Ты читал посты: [8] и [9]? Разбирался с ними? Какие вопросы возникли в процессе разбора?
Там, между прочим, готовые рабочие примеры были...
← →
Дмитрий_177 (2006-02-25 00:52) [32]блин... опять снова здорова.....((((((( но там же подразумевается что во всем файле будут храниться только точки и ничего больше... поетому мы можем написать эти строки при чтении из [8]:
size := GetFileSize(f, nil);
...
if FileRead(f, buf^, size) = size then begin
SetLength(Points, size div SizeOf(TPoint) + 1);
т.е. работать с размером файла, неволнуясь ч в том что там еще что-то может храниться...
или я не правильно понимаю эти примеры?
← →
Джо © (2006-02-25 01:02) [33]> [32] Дмитрий_177 (25.02.06 00:52)
> но там же подразумевается
> что во всем файле будут храниться только точки и ничего
> больше...
Ничего такого там не подразумевается. Напротив, в моем примере сделано все, чтобы можно было легко расширить класс для хранения записи/чтения чего-угодно.
← →
Джо © (2006-02-25 01:05) [34]В поток что угодно записать можно. И прочитать.
← →
Дмитрий_177 (2006-02-25 01:33) [35]так... завтра начинаю все сначала читать про потоки и про файлы... спасибо, Джо, а то я не понимал сначала... и писал ерунду...)))
← →
Дмитрий_177 (2006-02-27 15:51) [36]Джо, я сейчас расширяю ваш класс для хранения в нем изображений еще... У меня вопрос в том, что функциям "Add" надо всегда "overload;" приписывать? это же вроде как для того чтобы переписать функцию... а если я функцию не "Add" а "AddPoint" назову? всеравно "overload;" писать?
← →
Джо © (2006-02-27 16:01) [37]> а если я функцию не "Add" а "AddPoint" назову? всеравно
> "overload;" писать?
Нет, конечно. Overload нужен для объявления методов с одинаковыми именами, имеющими разные параметры.
← →
Дмитрий_177 (2006-02-27 16:30) [38]спасибо ))) еще один технический вопросик... при использовании раньше подобных ini-оберткок, как сказал Zeqfreed, можно было например сразу считать изображение в какойнибудь компонент, например в кнопку, а тут считывается сразу все, и будет храниться в памяти... ведь так? и потом оттуда уже записываем в кнопку или еще там куда... я так это понимаю?
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.03.12;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.014 c