0
votes

I'm attempting to read a file into a list of bytes in prolog, using swipl version 8.0.3.

:- use_module(library(readutil)).

try_read_byte(File):-
    open(File, read, Stream),
    get_byte(Stream, B),
    print(B).

try_read_char(File):-
    open(File, read, Stream),
    get_char(Stream, C),
    print(C).

try_read_char succeeds, but when I call try_read_byte, I get an error:

ERROR: No permission to read bytes from TEXT stream `<stream>(0x56413a06a2b0)'
ERROR: In:
ERROR:    [9] get_byte(<stream>(0x56413a06a2b0),_9686)
ERROR:    [8] try_read_byte("test.pl") at /home/justin/code/decompile/test.pl:5
ERROR:    [7] <user>

From reviewing the source code/documentation (https://www.swi-prolog.org/pldoc/man?section=error), it seems as if this is something like a type error, but I'm not able to figure out what to do based on that.

1
I would also not mind pointers to a better way to read a list of bytes from a file, as it seems surprising that I'd need to write that in pure prolog, rather than using a library predicate.Justin Blank
You need to say open(File, read, D, [type(binary)]). But do you really want bytes? (this is not specific to SWI)false
Thanks, post this as an answer, and I can accept it. I'm trying to write a parser for a binary format, so I think getting bytes really is what I want to doJustin Blank

1 Answers

1
votes

To read binary, you need to specify the option type(binary). Otherwise get_byte raises a permission_error as specified by the standard (section 8.13.1.3). This can be confusing as the user might be checking for correct permissions, which has nothing to do with the actual source of the problem.

try_read_byte(File):-
    open(File, read, Stream, [type(binary)])),
    get_byte(Stream, B),
    write(B).

I just tried this with Scryer Prolog, and it prints the first byte of the file as expected.