Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - arrays speichern
klausiemausie - Sa 28.02.09 19:18
Titel: arrays speichern
Sorry wenn ich frage, aber ich bin auf der Suche nach einem Beispielcode für das Speichern von arrays mit dem Savedialog, so dass der User einen Ort und einen Namen aussuchen kann für die Datei. hab suche schon benutzt und auch bruder google, wie man das mit savetofile löst hab ich gefunden, aber einen code wie das mit dem dialog klappt leider nicht. vielleicht hat ja einer von euch einen Beispielcode parat.
danke klaus
Delete - Sa 28.02.09 19:29
Delphi-Quelltext
1: 2:
| if SaveDialog.Execute then Speichern(SaveDialog.Filename); |
klausiemausie - Sa 28.02.09 19:30
hm ok, und was ist das "Speichern" in zeile 2, die variable die ich speichern will?
Bergmann89 - Sa 28.02.09 19:35
HI,
speichern is ne Proezedur und die würd ich so machen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure Speichern(FileName: String; array: array of String); var list: TStringList; var i: Integer; begin list := TStringList.Create; for i := 0 to High(array) do List.add(array[i]); list.saveToFile(FileName); list.free; end; |
und so rufst du die dann auf:
Delphi-Quelltext
1: 2:
| if SaveDialog1.Execute then Speichern(SaveDialog1.FileName, MyArray); |
so sollte das funzen habs aber noch net getestet...
MfG Bergmann
Keldorn - Sa 28.02.09 19:37
Die procedure, die für das Speichern verantwortlich ist ;-).
Poste bitte mal dein array bzw. Record. Was hast du drin?
Gugg mal bei
http://www.delphi-treff.de/tipps/object-pascal/ da findest du 2 Themen (dyn array abspeichern und records abspeichern) Beides geht nur, wenn Du im Array bzw Record nicht strings hast, sondern shortstrings (z.B. name:string[20]);
Ansonsten würde ich dir Streams empfehlen und alles einzeln speichern, hast du auf die Dauer und bei Änderungen mehr Freude dran.
Gruß Frank
klausiemausie - Sa 28.02.09 19:51
ich möchte 2 arrays speichern, einmal einen array wo nur zahlen von 0-2 drin stehen und einen wo auch grössere zahlen drin stehen, bis 10.000 oder so.
Keldorn - Sa 28.02.09 19:57
wenn beide zusammen in eine Datei sollen, dann gehts nicht mit den oben genannten, würde dir dann wirklich Streams empfehlen.
Prinzipiell gibt es da im Forum ein paar Beiträge, (z.B.
http://www.delphi-forum.de/viewtopic.php?t=66937&highlight=streams) ist zwar für Objekte, das Proinzip für ein dyn Array ist aber das gleiche.
poste aber trotzdem mal deine array-definition
klausiemausie - Sa 28.02.09 20:12
Region: Array[1..35] of single;
Zugehoerigkeit: Array[1..35] of byte;
jaenicke - Sa 28.02.09 20:57
Hier ein kleines Beispiel dafür, du brauchst nur zwei Buttons, dann sollte das so klappen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72:
| procedure TForm1.Button1Click(Sender: TObject); var Region: array[1..35] of Single; Zugehoerigkeit: array[1..35] of Byte; TestFile: TFileStream; TestMemStream: TMemoryStream; i: Integer; begin for i := Low(Region) to High(Region) do begin Region[i] := i; Zugehoerigkeit[i] := i; end;
TestFile := TFileStream.Create(ExtractFilePath(ParamStr(0)) + 'test.txt', fmCreate); try TestMemStream := TMemoryStream.Create; try TestMemStream.SetSize(Length(Region) * SizeOf(Single)); CopyMemory(TestMemStream.Memory, @Region[Low(Region)], Length(Region) * SizeOf(Single)); TestMemStream.Position := 0; TestFile.CopyFrom(TestMemStream, TestMemStream.Size);
TestMemStream.SetSize(Length(Zugehoerigkeit) * SizeOf(Byte)); CopyMemory(TestMemStream.Memory, @Zugehoerigkeit[Low(Region)], Length(Zugehoerigkeit) * SizeOf(Byte)); TestMemStream.Position := 0; TestFile.CopyFrom(TestMemStream, TestMemStream.Size); finally TestMemStream.Free; end; finally TestFile.Free; end; end;
procedure TForm1.Button2Click(Sender: TObject); var Region: array[1..35] of Single; Zugehoerigkeit: array[1..35] of Byte; TestFile: TFileStream; TestMemStream: TMemoryStream; i: Integer; begin TestFile := TFileStream.Create(ExtractFilePath(ParamStr(0)) + 'test.txt', fmOpenRead); try TestMemStream := TMemoryStream.Create; try TestMemStream.CopyFrom(TestFile, Length(Region) * SizeOf(Single)); CopyMemory(@Region[Low(Region)], TestMemStream.Memory, Length(Region) * SizeOf(Single));
TestMemStream.Position := 0; TestMemStream.CopyFrom(TestFile, Length(Zugehoerigkeit) * SizeOf(Byte)); CopyMemory(@Zugehoerigkeit[Low(Region)], TestMemStream.Memory, Length(Zugehoerigkeit) * SizeOf(Byte)); finally TestMemStream.Free; end; finally TestFile.Free; end;
for i := Low(Region) to High(Region) do begin ShowMessage(FloatToStr(Region[i])); ShowMessage(IntToStr(Zugehoerigkeit[i])); end; end; |
klausiemausie - Sa 28.02.09 21:13
mit dem 2. button lade ich das dann quasi wieder oder?
jaenicke - Sa 28.02.09 21:33
Ja, genau. Bei dynamischen Arrays müsstest du die Größe mit speichern.
klausiemausie - Sa 28.02.09 21:59
also ich hab das mal so ausprobiert, aber es funktioniert nicht. weil der soll ja inner showmessage den inhalt des jeweiligen arrays anzeigen im 2. button, aber der zeit immer nur 2 mal 1 , 2 mal die 2 , 2 mal die 3, also in jedem array nur i quasi, soll ja aber eig nich so sein oder?
Keldorn - Sa 28.02.09 22:21
also ein klein wenig solltest Du dich mit dem geposteten schon auseinandersetzen, nicht bloß abkopieren ;-)
| Zitat: |
for i := Low(Region) to High(Region) do
begin
Region[i] := i;
Zugehoerigkeit[i] := i;
end;
|
mußt du natürlich rausnehmen, das hat jaenicke nur zum testen reingeschrieben
klausiemausie - Sa 28.02.09 22:43
oh, total übersehen, ähm ja, ich habs mir natürlich durchgelesen, habs auch versucht zu verstehen, aber das ist ein anderes thema
klausiemausie - Sa 28.02.09 22:49
ja aber wenn da drin steht dass dann region[i]:=i is, dann wird ja der eig inhalt des arrays gar nich gespeichert....durch was muss ich das ersetzen?
Keldorn - Sa 28.02.09 22:53
das
| Zitat: |
Region: array[1..35] of Single;
Zugehoerigkeit: array[1..35] of Byte;
|
muß aus der buttonclick auch noch raus.
jaenicke - Sa 28.02.09 23:15
klausiemausie hat folgendes geschrieben : |
| oh, total übersehen, ähm ja, ich habs mir natürlich durchgelesen, habs auch versucht zu verstehen, aber das ist ein anderes thema |
Wenn du etwas nicht verstehst, dann frag doch nach. Das ist ja kein Problem, aber du musst eben sagen was genau du nicht verstehst. :wink:
klausiemausie - Sa 28.02.09 23:31
jetz hab ichs hinbekommen, funktioniert alles so wies geht, danke nochma
klausiemausie - Sa 28.02.09 23:42
eine frage hättich dann aber noch: wie bekomme ich es hin, dass der user den namen der Datei aussuchen kann, und dann beim laden die auch wieder auswählen kann?
jaenicke - Sa 28.02.09 23:43
Ich hoffe du hast den Quelltext auch verstanden, so dass du sowas dann auch selbst benutzen kannst, wenn du etwas ähnliches wieder brauchst. ;-)
Für das Auswählen der Datei gibt die Komponente TSaveDialog unter Dialogs.
// EDIT:
Aber Moment mal, das stand doch als erste Antwort oben schon da. :lol: ;-)
klausiemausie - So 01.03.09 00:01
jo dein beispiel hab ich an sich verstanden, nur mit dem savetodialog komm ich nich klar, so wie das oben als beispiel stand, hat es nicht gefunzt
jaenicke - So 01.03.09 00:10
Naja, du musst Execute aufrufen, wenn das erfolgreich war, dann musst du speichern. Wohin steht dann in FileName. Wie das dann genau aussieht, kommt dann auf deinen Code an.
Dass da eine Methode "Speichern" stand, war ja nur ein Beispiel dafür, dass du an der Stelle etwas mit dem erhaltenen Dateinamen machen musst.
Delete - So 01.03.09 00:22
So isses. Ohne die Daten zu kennen hätte ich ja nicht Konkretes dahin schreiben können. Also muss man nur eine Methode "Speichern" schreiben, die den Dateinamen übernimmt und alles ist in Butter.
klausiemausie - So 01.03.09 10:40
ihr sprecht in rätseln...
Delete - So 01.03.09 11:30
Wieso? Du wolltest wissen, wie Du per Dialog einen Dateinamen auswählen kannst, um in diese Datei zu speichern. Das hab ich Dir in der ersten Antwort verraten. Da ich aber Deine Daten nicht kannte, habe ich die auszuführende Speichermethode halt "Speichern" genannt. Diese musst Du nur noch schreiben, dann kannst Du den Code aus meiner Antwort 1:1 übernehmen.
klausiemausie - So 01.03.09 12:11
hm und für die prozedur speichern, kann ich da den code von jaenicke nehmen?
klausiemausie - So 01.03.09 12:23
was mir noch eingefallen ist, ich könnte ja einfach den namen der zu speichernden datei in ne stringvariable einlesen, kann ich die variabable in den code mit einfügen, dass er in ne variable datei schreibt? also hier in dieser zeile
TestFile := TFileStream.Create(ExtractFilePath(ParamStr(0)) + 'test.txt', fmOpenRead);
Delete - So 01.03.09 12:39
Natürlich, sonst macht der Dialog ja keinen Sinn.
Delphi-Quelltext
1: 2:
| TestFile := TFileStream.Create(OpenDialog.Filename, fmOpenRead); TestFile := TFileStream.Create(SaveDialog.Filename, fmOpenWrite); |
klausiemausie - So 01.03.09 13:32
gut hab ich so geändert, kommt aber jetz ne fehlermeldung "Cannot open file", wenn ich auf den button zum speichern klicke
Delete - So 01.03.09 13:34
Zeig mal den Code zum Speichern.
klausiemausie - So 01.03.09 13:38
procedure TForm1.Button8Click(Sender: TObject);
var
TestFile: TFileStream;
TestMemStream: TMemoryStream;
i: Integer;
begin
for i := Low(Region) to High(Region) do
begin
Region[i] := Region[i];
Zugehoerigkeit[i] := Zugehoerigkeit[i];
end;
TestFile := TFileStream.Create(SaveDialog1.Filename, fmOpenWrite);
try
TestMemStream := TMemoryStream.Create;
try
// Die Größe des MemoryStreams setzen
TestMemStream.SetSize(Length(Region) * SizeOf(Single));
// Den Speicherbereich des Arrays in den des Streams kopieren
CopyMemory(TestMemStream.Memory, @Region[Low(Region)], Length(Region) * SizeOf(Single));
// Die Position zum Lesen auf den Anfang setzen
TestMemStream.Position := 0;
// Und von dort aus den Inhalt in die Datei kopieren
TestFile.CopyFrom(TestMemStream, TestMemStream.Size);
TestMemStream.SetSize(Length(Zugehoerigkeit) * SizeOf(Byte));
CopyMemory(TestMemStream.Memory, @Zugehoerigkeit[Low(Region)], Length(Zugehoerigkeit) * SizeOf(Byte));
TestMemStream.Position := 0;
TestFile.CopyFrom(TestMemStream, TestMemStream.Size);
finally
TestMemStream.Free;
end;
finally
TestFile.Free;
end;
end;
Delete - So 01.03.09 13:41
| Zitat: |
Delphi-Quelltext 1: 2: 3: 4: 5:
| for i := Low(Region) to High(Region) do begin Region[i] := Region[i]; Zugehoerigkeit[i] := Zugehoerigkeit[i]; end; | |
Ähmm... wozu soll das gut sein? Und Du führst den Dialog ja gar nicht aus.
klausiemausie - So 01.03.09 13:47
öhm gute frage, das stand im beispiel von jaenicke mit region[i]:=i, da das ja nich erwünscht war hab ich das geändert, is eig sinnlos ja^^. wie muss ich den code den ändern, dass er ausgeführt wird?
Delete - So 01.03.09 13:49
Das stand doch bereits in meiner ersten Antwort.
Delphi-Quelltext
1: 2: 3: 4: 5:
| if SaveDialog1.Execute then begin TestFile := TFileStream.Create(SaveDialog1.Filename, fmOpenWrite); end; |
klausiemausie - So 01.03.09 14:39
gut das funktioniert, und wie erzähl ich dem savedialog nun, dass er das als ne text datei speichert? weil es kommt jetz die selbe fehlermeldung, allerdings erst wenn ich einen dateinamen eingebe und auf speichern klicke
Keldorn - So 01.03.09 14:42
zeig nochmal deinen aktuellen code und setz den bitte in Delphitags, liest sich besser
klausiemausie - So 01.03.09 14:44
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| procedure TForm1.Button8Click(Sender: TObject); var
TestFile: TFileStream; TestMemStream: TMemoryStream; i: Integer; begin for i := Low(Region) to High(Region) do begin Region[i] := Region[i]; Zugehoerigkeit[i] := Zugehoerigkeit[i]; end; if SaveDialog1.Execute then begin TestFile := TFileStream.Create(SaveDialog1.Filename, fmOpenWrite); try TestMemStream := TMemoryStream.Create; try TestMemStream.SetSize(Length(Region) * SizeOf(Single)); CopyMemory(TestMemStream.Memory, @Region[Low(Region)], Length(Region) * SizeOf(Single)); TestMemStream.Position := 0; TestFile.CopyFrom(TestMemStream, TestMemStream.Size);
TestMemStream.SetSize(Length(Zugehoerigkeit) * SizeOf(Byte)); CopyMemory(TestMemStream.Memory, @Zugehoerigkeit[Low(Region)], Length(Zugehoerigkeit) * SizeOf(Byte)); TestMemStream.Position := 0; TestFile.CopyFrom(TestMemStream, TestMemStream.Size); finally TestMemStream.Free; end; finally TestFile.Free; end;
end; end; |
Keldorn - So 01.03.09 14:55
warum hast Du
| Zitat: |
for i := Low(Region) to High(Region) do begin Region[i] := Region[i]; Zugehoerigkeit[i] := Zugehoerigkeit[i]; end;
|
noch drin?
| Zitat: |
TestFile := TFileStream.Create(SaveDialog1.Filename, fmOpenWrite);
|
aus der oh:
| Zitat: |
fmOpenWrite : Die Datei wird ausschließlich zum Schreiben geöffnet. Beim Schreiben in die Datei wird der aktuelle Inhalt vollständig ersetzt.
fmCreate :Es wird eine Datei mit dem angegebenen Namen angelegt. Ist eine Datei mit diesem Namen bereits vorhanden, wird die Datei geleert und zum Schreiben geöffnet.
|
was meinst Du, was Du verwneden mußt, wenn die Datei noch nicht exisitiert? fmopenwrite oder fmcreate? und warum wirst Du mit openwrite Deine Fehlermeldung erhalten ;-)?
Edit: Achso und als Text-datei wird der stream nicht gespeichert! du kannst das nicht mit einem editor öffnen und bearbeiten.
klausiemausie - So 01.03.09 15:27
schubba, jetz funzt es, danke an alle
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!