Reputation: 23
I am trying to store multiple files into one filestream and then dump them. For that, while merging them, I use buffers like this:
SetLength(header, 10);
header := Bytesof(Inttohex(SizeofStream, 10));
mystream2.WriteBuffer(header, Length(header));
mystream2.CopyFrom(mystream1, SizeofStream);
Also, in some special cases, where I need to distinguish two specific files, I use:
SetLength(header, 20);
header:= Bytesof(Inttohex(BS2.Size, 10) + Inttohex(BS3.Size, 10));
mystream2.WriteBuffer(header, Length(header));
mystream2.CopyFrom(BS2, 0);
mystream2.CopyFrom(BS3, 0);
So that I can easily decode it by taking first 10 bytes for the first stream's size & next 10 for later ones.
While restoration, I need to store all those headers into a Stringlist so that I can easily process them one after another using a loop. I tried using this:
FEncoding := TEncoding.Default;
SetLength(Buffer, mystream1.size);
myStream1.ReadBuffer(Pointer(Buffer)^, Length(Buffer));
SL1.Clear;
SL1.SetText(PWideChar(FEncoding.GetString(Buffer)));
But it doesn't work or even if it does, it just adds a few of the first buffers, that too in a single line instead of separate line for each buffer in String list. Can ya please tell me how to do it?
Upvotes: 0
Views: 1132
Reputation: 163287
Your WriteBuffer
call doesn't work the way you think it does. Header
is a TBytes
, which is a dynamic array. That means that the header
variable itself is just a pointer to the actual array data. WriteBuffer
writes the value that you pass it, which in this case is the pointer to the array data. To write the array data to the buffer, you need to dereference the pointer:
mystream2.WriteBuffer(header[0], Length(header));
To read from the stream, you need to invert all the steps you performed when writing. First, prepare the header
buffer:
SetLength(header, 10);
Next, read the header from the stream:
mystream1.ReadBuffer(header[0], Length(header));
Finally, read the file data:
BS1.CopyFrom(mystream1, StrToInt64('$' + TEncoding.Default.GetString(header)));
The above assumes that you know there's just one file. If you don't know in advance how many files your stream contains, then you need some way of encoding that, too. You could add a header field to the start, before the first size header. Or you could just repeat the above three steps (SetLength
, ReadBuffer
, CopyFrom
) until you reach the end of the stream.
You might also investigate using existing serialization technology instead of attempting to invent your own. For example, the tar format is one popular way of representing a stream of many files.
Upvotes: 2