Read/Write a file as Binary into a MemoryBlock

I have the MemoryBlock page in front of me and I do not saw anyway to load a file contents as a block of data.

But I may be wrong.

I am searching something like MemoryBlock.Binary = BinaryStream.Read(File_Length) (or similar).

To load a text file, I may load its contents in TextArea; many years ago, I used the same kind of things to load the file whole data into memory. But in Xojo ?

Of course, I can use a loop and MB.Byte(Loop_Idx) = Item_BS.Read(1), but this will take ages if the file have some weight.

Dim readFile As FolderItem = GetOpenFolderItem("text") If readFile <> Nil And readFile.Exists Then Dim ReadStream As BinaryStream = BinaryStream.Open(readFile, False) ReadStream.LittleEndian = True Dim WriteFile As FolderItem = GetSaveFolderItem("", "") If writeFile <> Nil Then Dim writeStream As BinaryStream = BinaryStream.Create(writeFile, True) writeStream.LittleEndian = True Do Until ReadStream.EOF writeStream.WriteInt32(ReadStream.ReadInt32) Loop writeStream.Close End If readStream.Close End If

If the data is purely text, you can use TextInputStream.Read(All) to get the content as a string directly.
The same does a BinaryStream.Read.
Keep in mind that String and classic MemoryBlock convert into each other implicitly, so no need to employ a MemoryBlock as buffer for pure string data.

Thank you for your answers.

No TEXT here, only binary data.

So, unlike Text where you can read the whole text file contents in a single line, a Binary File cannot be read all at once and eventually changed at will, appended, resized, etc.

Specifically, I want to be able to do in pseudo language:

[code]Dim Binary_Data As BlockOfMemory // Yes, this does not exists
Dim File_BS As BinaryStream

// Load all the data at once
Binary_Data = File_BS.ReadAll

// Here I want to be able to made changes to the
// Binary_Data (add, remove, modify, etc.)
// And I do not want to be annoyed with Indians (little / gross / small / enlarged…)
// In short: make binary changes to the file contents.[/code]

BlockOfMemory can be replaced with a MemoryBlock, but it does not have a ReadAll function…

@Brian:
To read the whole Text file contents I use:

TextArea1.Text = TextInputStream1.ReadAll

How many times it will takes (with your code) to read a 500 MB file ?

Sure it can:
Dim MB as MemoryBlock = BinStream.Read(Binstream.Length)

Changed at will yes. You can in theory use BinaryStream.Position to set the “write marker” and then one of the several write methods to change that part in a readwrite stream. Cutting away pieces could be difficult, but as you are using a MemoryBlock as buffer it is possibly the easiest way to overwrite the whole file with the new MB content when you’re done with BinStream.Write(MB)

Thanks Ulrich.

I certainly am tired (Ich bin müde as said my father…)

To save the changes, I can save the result in another file. The idea can be:

Copy bits of the original Binary data from one MemoryBlock into a second one, and when finished, save the whole into a brand new file.

What may have been bothered me was the optional encoding (in MemoryBloxk.Read…): an encoding for a binary stream ???
(Yes, it may be of use, sometimes.)

Yes, tired.

But the two entries in the LR talks about Text, and I want Binary data.
Also (as I wrote above) where / how do I load the binary data…

The idea is to do what is figured below (false code):

[code]Dim MB As New MemoryBlock(512000) // If possible… not tested

MB.Something = BStream.Read(512000)[/code]

As I said: Keep in mind that String and classic MemoryBlock convert into each other implicitly.

That’s what the Xojo framework tried to fix: String and MemoryBlock are very similar data types and an be exchanged. Only String is most often used to display text, where it obviously needs an Encoding to show the intended characters, but it does not have to and can contain pure binary data as well.

In your example, it is not necessary to dim the MB with a certain size. BinaryStream returns a string with a certain size (in your example a maximum of 512000) which you can assign to the memoryblock like written.

You can read and write binary data with a TextStream, too. The String data type doesn’t have to be text. It can be binary, too.

And as has been mentioned, you can read/write an entire file with BinaryStream.

Thanks Tim for your answer.

The question is: “where do I put the read data" ?

Apparently, I am stuck there.

After some minutes, I tested:

[code] Dim data_FI As FolderItem
Dim data_BS As BinaryStream
Dim data As String

data_FI = GetOpenFolderItem(“”)

data_BS = BinaryStream.Open(data_FI)

data = data_BS.Read(1000)

data_BS.Close[/code]

It looks stupid (to me) to send Binary data into a string variable; that is the reason why I do not explored that earlier.

Edit:
I checked, data (the string) Encoding is Nil.

Also: have a good time to the one who will have to read that code to understand it (I think).

It depends on what you want to do with it. If you’re just going to write it out again without modifying it, for example to send it over a socket to another program, using a String is easiest. If you’re going to modify it, then a MemoryBlock might be best, or even a Structure. You can adjust your code to use a memoryblock by changing just one line.

Dim data_FI As FolderItem
Dim data_BS As BinaryStream
Dim data As MemoryBlock      // change string to memoryblock, and don't create one with New

data_FI = GetOpenFolderItem("")
  
data_BS = BinaryStream.Open(data_FI)
  
data = data_BS.Read(1000)

The difference between text and binary data in Xojo is mostly semantic. They are largely interchangeable. You could use a TextInputStream in this example and it would function exactly the same. So BinaryStream, TextInputStream, String, MemoryBlock, it’s pretty much all the same.

A string with Nil encoding is binary data. Just a bag of bytes. Apply an encoding and it becomes text. But that is largely semantics as well. A string with Nil encoding can be displayed in a TextArea and be readable. A string with an encoding can still function as binary data (the encoding might not be valid, but it doesn’t matter if you’re using it as binary).

Hi Tim,

Thank you for your kind explanation.

My mind structure is… strange…

If I have to light a fire, I will take newspaper, not fuel for cars (or plane) and small wood, then larger wood.