Write binary data to a file

Use only in the MuPAD Notebook Interface.

This functionality does not run in MATLAB.


writebytes(filename | n, list | hfarray, <format>, <BigEndian | LittleEndian>, <Force>)


writebytes(file, list) writes a list of MuPAD® numbers to a file.

writebytes(file, hfarray) writes an array of type DOM_HFARRAY to a file.

writebytes lets you write arbitrary files and interpret their contents as a sequence of numbers.

The results of writebytes depend on the interpretation of the binary data set by the format option. When writing to a file, you can interpret it as a stream of Byte, SignedByte, Short, SignedShort, Word, SignedWord, Float or Double. These are standard formats used by many program packages to write data. See Example 1.

This function is particularly useful when you work on data provided by or intended for external programs. For example, you can use it to implement encryption or compression algorithms in MuPAD. See Example 2.

You can specify the file directly by its name. If a file name is specified, writebytes creates a new file or overwrites an existing file. If a file name is specified, writebytes also opens and closes the file automatically. If WRITEPATH has no value writebytes interprets the file name as a pathname relative to the "working directory." Absolute path names are processed by writebytes, too.

    Note:   The meaning of "working directory" depends on the operating system. On Microsoft® Windows® systems and on Mac OS X systems, the "working directory" is the folder where MuPAD is installed. On UNIX® systems, it is the current working directory in which MuPAD was started; when started from a menu or desktop item, this is typically the user's home directory.

If a file name is specified, each call to writebytes opens the file at the beginning. If the file was opened via fopen, subsequent calls of writebytes with the corresponding file descriptor start at the point in the file that was reached by the last writebytes command. Hence, if you want to write a file by portions, you must open it with fopen and use the returned file descriptor instead of the filename. See Example 3.

    Note:   If the file is to be opened via fopen, be sure to pass the flag Raw to fopen. Otherwise, writebytes throws an error.

Be sure to write the data in the appropriate way. You must know the format used by the program which will be reading the file.

When writing data via writebytes, each entry in the list is checked for whether it can be converted to the specified format. If this is not the case, writebytes throws an error. See Example 4.

When writing an array of type DOM_HFARRAY, only Double is allowed as the binary format. If no format option is given such arrays are written as doubles. See Example 7.

If an array of type DOM_HFARRAY with complex numbers is written to a file, then first the real parts of the elements are written and then the complex parts are written to the file. Because readbytes can only read real values, first one have to create the real and then the complex part to reconstruct the complex array. See Example 9.

Environment Interactions

The function writebytes is sensitive to the environment variable WRITEPATH. If this variable has a value, the file is created in the corresponding directory. Otherwise, the file is created in the "working directory."


Example 1

Write a sequence of numbers to the file test.tst with the default settings. Then, load them back in:

writebytes("test.tst", [42, 17, 1, 3, 5, 7, 127, 250]):

Read the above data with some other option: SignedByte interprets all values from 0 to 127 exactly as Byte does. Higher values x, however, are interpreted as x - 256. For example, 250 - 256 = - 6:

readbytes("test.tst", SignedByte)

Short interprets two bytes to be one number. Therefore, the eight written bytes are interpreted as four numbers. For example, the first 2 bytes yield 42 28 + 17 = 10769:

readbytes("test.tst", Short)

With the flag LittleEndian, the byte order is reversed. For example, the first 2 bytes now yield 17 28 + 42 = 4394:

readbytes("test.tst", Short, LittleEndian)

Word interprets four bytes to be one number. Therefore, the eight written bytes give two numbers. The first 4 bytes yield 10769 216 + 259 = 705757443:

readbytes("test.tst", Word)

Double interprets eight bytes to represent one floating-point number. The interpretation is machine dependent and may be different for you:

readbytes("test.tst", Double)

Example 2

Use readbytes and writebytes to encrypt the file created in the previous example with a simple "Caesar type encoding": Any integer x (a byte) is replaced by x + 13 mod 256:

L := readbytes("test.tst"): 
L := map(L, x -> (x + 13 mod 256)):
writebytes("test.tst", L):

Knowing the encryption and its key, you can successfully decrypt the file:

L := readbytes("test.tst")

map(L, x -> (x - 13 mod 256))

delete L:

Example 3

Use fopen to write and read a file in portions:

n := fopen("test.tst", Write, Raw):               
for i from 1 to 10 do writebytes(n, [i]) end_for: 

Equivalently, you can write all data in one go:

n := fopen("test.tst", Write, Raw):               
writebytes(n, [i $ i = 1..10]):

Read the data byte by byte:

n := fopen("test.tst", Read, Raw): 
readbytes(n, 1), readbytes(n, 1), readbytes(n, 1);

The next command reads in portions of 5 bytes each:

n := fopen("test.tst", Read, Raw): 
readbytes(n, 5), readbytes(n, 5);

delete n, i:

Example 4

An error is thrown if the data do not match the specified format. Here, -5 does not match Byte. This format does not include negative numbers:

writebytes("test.tst", [42, 17, -5, 7], Byte)
Error: The argument is invalid. [writebytes]

Example 5

Here is what happens if the number of bytes in the file does not match a multiple of units of the specified format. Because both SignedShort and Float consist of an even number of bytes, the trailing 5-th byte corresponding to 11 is ignored:

writebytes("test.tst", [42, 17, 7, 9, 11], Byte):
readbytes("test.tst", SignedShort), 
readbytes("test.tst", Float)

Example 6

Specify byte ordering by using BigEndian and LittleEndian:

writebytes("test.tst", [129, 255, 145, 171, 191, 253], Byte):
L1 := readbytes("test.tst", Short, BigEndian)

L2 := readbytes("test.tst", Short, LittleEndian)

Look at the data in a binary representation. (See numlib::g_adic for details). The effect of using LittleEndian instead of BigEndian is to exchange the first 8 bits and the last 8 bits of each number:

map(L1, numlib::g_adic, 2)

map(L2, numlib::g_adic, 2)

delete L1, L2:

Example 7

Write the elements of a DOM_HFARRAY to a file. All the elements are double-precision values, and writebytes does not allow writing the elements of the array in another format than Double.

   [   0.2703,   12.8317, -33.1531, 9999.9948, 0.2662,  -14.3421, 
    1000.1801,    0.4521, -34.6787,  -67.3549, 0.6818,   13]):
writebytes("test.tst", A):

But if we try to write the elements as bytes we will get an error.

writebytes("test.tst", A, Byte);
Error: The argument is invalid. [writebytes]
delete A:

Example 9

Write a DOM_HFARRAY with complex numbers to a file and try to reconstruct it by reading the data.

A := hfarray(1..2, 1..3,
             [[2342.133 + 56*I, -342.56, PI + I],
              [           -3*E, I^2 + I,     13]]);
writebytes("test.tst", A);
fd := fopen("test.tst", Read, Raw):   
B := readbytes(fd, ReturnType = [DOM_HFARRAY, 2, 3]);
C := readbytes(fd, ReturnType = [DOM_HFARRAY, 2, 3]);
bool(A = B + C*I);

delete A, B, C, fd:

Example 10

Suppose you have a DOM_HFARRAY with entries which are integer numbers between -32768 and 32767 and we want to write this data as SignedShort to a file. If you try it without the option Force, you will get an error because a floating-point number of type DOM_FLOAT cannot be written as a SignedShort. With the option Force, writebytes tries to convert the floating-point number to a signed word and writes it in any case to the file.

A:=hfarray( 1..2,1..3, [[234,-32768,1],[32767,-12111,-3]]);
writebytes("test.tst", SignedShort, A):

Error: The argument is invalid. [writebytes]
writebytes("test.tst", SignedShort, Force, A):
l:= readbytes("test.tst", SignedShort);
op(A,i)-l[i] $i=1..6;

delete A, l:



The name of a file: a character string


A file descriptor provided by fopen: a positive integer. The file must have been be opened using the fopen-flag Raw.


A list of MuPAD numbers to be written to the file. The entries must match the specified format.


An array of type DOM_HFARRAY.


The format of binary data, specified as Byte, SignedByte, Short, SignedShort, Word, SignedWord, Float, and Double.


Byte, SignedByte, Short, SignedShort, SignedWord, Word, Double, Float

The format of the binary data. The default format is Byte.

A byte is an 8-bit binary number. Therefore, a byte can have 28 different values. For Byte, these are the integers from 0 to 255. For SignedByte, they are the integers from - 128 to 127.

With Byte, the data are read/written in 8-bit blocks, interpreted as unsigned bytes. When writing, the numbers are checked for being in the range from 0 to 255.

With SignedByte, the data are read or written using the 2-complement.

Byte is the default format.

A "short" is a 16-bit binary number (2 bytes). Therefore, a "short" can have 216 different values. For Short, these are the integers from 0 to 65536. For SignedShort, they are the integers from - 32768 to 32767.

The semantics of Short or SignedShort is analogous to that of Byte or SignedByte, respectively.

A "word" is a 32-bit binary number (4 bytes). Therefore, a "word" can have 232 different values. For Word, these are the integers from 0 to 4294967296. For SignedWord, they are the integers from - 2147483648 to 2147483647.

The semantics of Word or SignedWord is analogous to that of Byte or SignedByte, respectively.

The format of the binary data. The default format is Byte.

A "float" is a 32-bit representation of a real number (4 bytes). A "double" is a 64-bit representation of a real number (8 bytes).

    Note:   Floats and doubles are read/written in the format of the machine/operating system MuPAD is currently running on. Therefore, the results may differ between different platforms.

Binary files containing floating-point numbers are, in general, not portable to other platforms.

See the flags BigEndian and LittleEndian for details on the byte ordering.

See Example 1 for an overview over the different format options.

BigEndian, LittleEndian

The byte ordering: either BigEndian or LittleEndian. The default ordering is BigEndian.

BigEndian and LittleEndian specify the order in which the bytes are arranged for Short, SignedShort, Word, SignedWord, Float, and Double.

For all formats, the data are written in 8-bit blocks (bytes). This also includes the formats where a unit is longer than one byte (all formats but Byte and SignedByte). With BigEndian, the bytes with the most significant bits ("high bits") are written first. With LittleEndian, the bytes with the least significant bits are written first.

If, for example, Short is selected, there are 16 bits that are to be written. If you pass BigEndian, first the byte with the bits for 215 to 28 and then the byte with the bits for 27 to 20 are written. If you specify LittleEndian, the order of the bytes is reversed.

BigEndian and LittleEndian have no effect if the formats Byte or SignedByte are specified.

BigEndian is the default byte order.

See Example 6 for the effects of BigEndian and LittleEndian.


Write the binary data in any case even if the numbers does not match the given format.

If the option Force is set, data are written in the given format, e.g. Byte even if they does not have the right format. E.g. 100.00 is a DOM_FLOAT and normally writebytes only writes this data if the format is Float or Double. With the option Force the value is written as a Byte. Cf. Example 10.

If the given value does not fit the given data format, the written value is not specified. E.g. 53425.00 written as a Byte can be 177 which is 53425.00 mod 256 or just 0. But for sure 100.00 is written as 100.

Return Values

The void object null() of type DOM_NULL.

Was this topic helpful?