YottaDB: writing a binary file

93 views
Skip to first unread message

ed de moel

unread,
Jan 24, 2023, 11:09:28 AMJan 24
to
I'm trying to write a binary file.
I'm end up with a file that contains the UTF-8 escapes for the bytes with a value between 128 and 255.
To demonstrate: I tried this:
Set file="x.tmp"
Open file:(newversion:stream:nowrap:nodelimiter:chset="M")
Use file For i=0:1:255 Write $Char(i)
c file
the file that gets created has 385 bytes, while I would expect 256.

Any suggestions?

K.S. Bhaskar

unread,
Jan 25, 2023, 7:01:45 AMJan 25
to
Ed, try $ZCHAR() (https://docs.yottadb.com/ProgrammersGuide/functions.html#zchar) which refers to bytes. $CHAR() (https://docs.yottadb.com/ProgrammersGuide/functions.html#char) refers to characters.

Regards
– Bhaskar

K.S. Bhaskar

unread,
Jan 25, 2023, 7:03:16 AMJan 25
to
Also, remember to set $X to zero before closing the file. Otherwise, you may get a line terminator added at the end.

Regards
– Bhaskar

ed de moel

unread,
Jan 25, 2023, 10:14:50 AMJan 25
to
That works, but it means that instead of
Write blob
I have to
For ii=1:1:$Length(blob) Write $Zchar($Ascii(blob,ii))


K.S. Bhaskar

unread,
Jan 25, 2023, 10:59:48 AMJan 25
to
Ed, I'm not sure exactly what you are trying to do, but hope this helps:

YDB>for i=1:1:256 s $zextract(x,i)=$zchar(i-1)

YDB>write $zlength(x)
256
YDB>set f="/tmp/tmp.tmp" open f:(newversion:chset="m")

YDB>use f write x set $x=0 close f

YDB>zsystem "ls -l /tmp/tmp.tmp"
-rw-r--r-- 1 bhaskar gtc 256 Jan 25 10:58 /tmp/tmp.tmp

YDB>write $zchset
UTF-8
YDB>

Regards
– Bhaskar

ed de moel

unread,
Jan 25, 2023, 11:10:31 AMJan 25
to
I'm building a jpg (image) file from a web-upload.
I'll try your suggestion.

Thanks,
Ed

Sam Habiel

unread,
Jan 26, 2023, 8:26:34 AMJan 26
to
Ed,

Unfortunately, reading and writing a binary file is pretty difficult.

I have code that is working and is in production:

https://gitlab.com/YottaDB/Util/YDB-Web-Server/-/blob/master/src/_ydbwebapi.m#L118

Read is:

1. Open with "FIXED": O PATH:(REWIND:READONLY:FIXED:CHSET="M")
2. Read length-limited reads: N X F R X#4079:0 S HTTPRSP(C)=X,C=C+1 Q:$ZEOF
3. Close file.

https://gitlab.com/YottaDB/Util/YDB-Web-Server/-/blob/master/src/_ydbwebrsp.m#L239

Write is:

1. Open with STREAM, NOWRAP and CHSET of M: o file:(newversion:stream:nowrap:chset="M")
2. Write Data
3. Set $X to zero
4. Close file.

Keep in mind that if you are operating in UTF-8 mode (the default), you always need to use the byte operators $ZCHAR, $ZASCII, and $ZLENGTH and $ZPIECE.

--Sam

ed de moel

unread,
Jan 26, 2023, 12:25:43 PMJan 26
to
It's tricky indeed.
In my case, this is what ended up working best:

-- code that builds the binary blob (this code works for both YottaDB and Iris, so, no $ZChar in there) --
Open file:(newversion:stream:nowrap:nodelimiter:chset="M") Use file
For ii=1:1:$Length(blob) Write *$Ascii(blob,ii)
Set $X=0
Close file

(And I'm sure I could have used $ZChar($Ascii(blob,ii)) instead of *$Ascii(blob,ii),
but with *$Ascii(blob,ii) the code remains just a tad closer to the standard.)

Thanks for all the help,
Ed
Reply all
Reply to author
Forward
0 new messages