Entwickler-Ecke

Dateizugriff - [Frage] Dateien in String umwandeln und wieder zurück


Pepp3r - Di 14.09.10 12:46
Titel: [Frage] Dateien in String umwandeln und wieder zurück
Hi,
ich schreibe gerade an eine Filmdatenbank. Zum speichern der Daten verwende ich eine xml. Weil ich es doof finde die Covers in einem seperaten ordner zu speichern, möchte ich die Bilddateien als string in der xml speichern und später wieder umwandeln. Ich verwende folgende Proceduren(q'n d):


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:
procedure TForm1.Button1Click(Sender: TObject); //DataToStr
var
DataSize: DWord;
DataStr: string;
DataFile: file;
DataBuf: Byte;
i: DWord;
txt: TextFile;

begin
AssignFile(DataFile, extractfilepath(paramstr(0))+'test.bmp');
Reset(DataFile, 1);
DataSize := SizeOf(DataFile);
SetLength(DataStr, DataSize);
if DataSize > 0 then
begin
for i := 0 to (DataSize-1do
begin
BlockRead(DataFile, DataBuf, 1);
DataStr := DataStr + IntToStr(DataBuf);
end;
CloseFile(DataFile);
end;
AssignFile(txt,extractfilepath(paramstr(0))+'test.txt');
rewrite(txt);
Write(txt, DataStr);
Flush(txt);
CloseFile(txt);
end;

procedure TForm1.Button2Click(Sender: TObject); //StrToData
var
DataSize: DWord;
DataStr: string;
DataFile: file;
DataBuf: Byte;
i: DWord;
txt: TextFile;
begin
AssignFile(txt,extractfilepath(paramstr(0))+'test.txt');
reset(txt);
read(txt, DataStr);
CloseFile(txt);

AssignFile(DataFile, extractfilepath(paramstr(0))+'test2.bmp');
Rewrite(DataFile, 1);
DataSize := length(datastr);
if DataSize > 0 then
begin
for i := 0 to (DataSize-1do
begin
databuf := byte(datastr[i]);
BlockWrite(DataFile, DataBuf, 1);
end;
CloseFile(DataFile);
end;
end;


Das klappt auch eigentlich. Leider nicht ganz, die txt. datei beim speichern ist zu groß, demnach die daraus gwonnene Bildadatei auch.
Weiß jemand woran es liegt?
Gruß
Pepp3r


Gausi - Di 14.09.10 13:07

user profile iconPepp3r hat folgendes geschrieben Zum zitierten Posting springen:
Weiß jemand woran es liegt?

Ja. :mrgreen:


Delphi-Quelltext
1:
2:
3:
4:
5:
for i := 0 to (DataSize-1do
begin
BlockRead(DataFile, DataBuf, 1);
DataStr := DataStr + IntToStr(DataBuf);
end;

Hier wandelst du einzelne Bytes in Strings um. Kann man machen, allerdings wird aus dem Byte $FF der String "255", aus einem Byte werden also drei.
Wenn du die Binärdaten unbedingt in einer XML-Datei speichern willst, dann wäre evtl. Base64 [http://de.wikipedia.org/wiki/Base64] was für dich.

Oder du entwirfst ein eigenes binäres Dateiformat, dass sämtliche Informationen speichern kann, die du benötigst.


Pepp3r - Di 14.09.10 13:19

Hi,
danke für die Antwort.
Die Base64 geschichte scheint mir ein wenig zu kompliziert für meine zwecke. Genauso wie der entwurf eines eigenen Dateiformats.
Es muss eine einfachere "methode" (:D) geben. Wir mussten damals in der Schule ein Programm zum Cäsar-verschlüsseln von Dateien programmieren.
Da haben wir die Datei in binärcode umgewandelt und die bits verschoben (oder so). Auf diese weise muss es also auch gehen.
edit:// denkfehler, der binärcode muss ja auch als string abgespeichert werden :?


Gausi - Di 14.09.10 13:21

Du könntest die einzelnen Bytes auch als zweistellige Hexadezimalzahl im String speichern. Dafür gibt es die Funktion IntToHex (oder so ähnlich).


Pepp3r - Di 14.09.10 13:44

etwa so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
for i := 0 to (DataSize-1do //schreiben
begin
BlockRead(DataFile, DataBuf, 1);
DataStr := DataStr + IntToHex(databuf, 2);
end;
//...
for i := 0 to (DataSize-1do //lesen
begin
databuf := byte(datastr[i]);
BlockWrite(DataFile, DataBuf, 1);
end;
?

Es kommen immernoch nicht die richtiegn daten dabei heraus :(


Gausi - Di 14.09.10 14:42

Ne, beim auslesen aus der XML-Datei musst du dann immer zwei Zeichen lesen, und diese als Hexadezimaldarstellung für ein Byte interpretieren.


Delete - Di 14.09.10 18:28

user profile iconPepp3r hat folgendes geschrieben Zum zitierten Posting springen:
Hi,
danke für die Antwort.
Die Base64 geschichte scheint mir ein wenig zu kompliziert für meine zwecke.

Was ist daran kompliziert eine fertige Funktion aufzurufen?


Pepp3r - Mi 15.09.10 00:39

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconPepp3r hat folgendes geschrieben Zum zitierten Posting springen:
Hi,
danke für die Antwort.
Die Base64 geschichte scheint mir ein wenig zu kompliziert für meine zwecke.

Was ist daran kompliziert eine fertige Funktion aufzurufen?


nun, ich habe mich mit dem thema base64 noch nicht beschäftigt, und ich will keine funktion aufrufen von der ich nicht genau weiß was sie macht.
mein ehrgeiz lässt es mich erstmal selbst versuchen :)


Pepp3r - Mi 15.09.10 04:13

Ich habe das Problem zwar nicht so gelöst wie ich es wollte, aber ich verwende jetzt die Indy-Komponente IdCoderMIME.
Es funktioniert und das ist schonmal gut.
Danke an alle Helfer. Für Leute die zukünftig dasselbe Problem haben, habe ich eine Beispielanwendung angehangen.
Gruß
Jonas