# Read a number of bytes from a stream

**URL:** <https://swi-prolog.discourse.group/t/read-a-number-of-bytes-from-a-stream/6867>\
**Category:** Help!\
**Created:** [October 2, 2023, 8:50am UTC](https://swi-prolog.discourse.group/t/read-a-number-of-bytes-from-a-stream/6867 "2023-10-02T08:50:11Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [October 2, 2023, 8:50am UTC](https://swi-prolog.discourse.group/t/read-a-number-of-bytes-from-a-stream/6867/1 "2023-10-02T08:50:11Z")

</div>

I’m using: SWI-Prolog version 9.1.16

I want the code to: read a number of bytes from a file

But what I’m getting is: either characters, or copying from on one stream to another

The question: do we have a predicate for reading from a stream to a Prolog data structure (list of codes?) that takes a “number of bytes” argument?

I found copy\_stream\_data/3 which _almost_ does it, but now my data is another stream 🙂

There are many predicates that read from streams, but I didn’t find any that takes a length parameter.

There is read\_string/3, but I am not sure if this way of using it is officially supported. Here is an example of how it did what I need:

```prolog
?- new_memory_file(M),
   insert_memory_file(M, 0, [1,2,0,0,4]),
   setup_call_cleanup(open_memory_file(M, read, In, [encoding(octet)]),
       read_string(In, 3, Str),
       close(In)),
   string_codes(Str, Bytes). 
M = <memory_file>(0x6000009dc8f0),
In = <stream>(0x600000ed8200),
Str = "\u0001\u0002\u0000",
Bytes = [1, 2, 0].

```

I double-checked that this works for ordinary files, too:

```prolog
$ echo -e '\x01\x02\x00\x00\x03' > foo
$ swipl -q
?- setup_call_cleanup(open(foo, read, In, [encoding(octet)]),
       read_string(In, 3, Str),
       close(In)),
   string_codes(Str, Bytes).
In = <stream>(0x60000373c200),
Str = "\u0001\u0002\u0000",
Bytes = [1, 2, 0].

```

However, the docs explicitly warn against this:

> Note that _characters_ must be read as _Unicode code points_, _not_ bytes.

Should I avoid using read\_string/3 for this? Is there a predicate I overlooked that can be used instead? Or do I go ahead and use get\_byte/2 in a loop?

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [October 2, 2023, 9:09am UTC](https://swi-prolog.discourse.group/t/read-a-number-of-bytes-from-a-stream/6867/2 "2023-10-02T09:09:15Z")

</div>

> [@Boris](#):
>
> Should I avoid using [read\_string/3](https://www.swi-prolog.org/pldoc/doc_for?object=read_string/3) for this?

I think that is fine. The docs are a bit misleading. read\_string/3 reads _characters_, each of which may be multiple bytes. If you use an encoding where a character is a byte, you are (thus) fine.

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [October 2, 2023, 9:31am UTC](https://swi-prolog.discourse.group/t/read-a-number-of-bytes-from-a-stream/6867/3 "2023-10-02T09:31:56Z")

</div>

This is an opportunity to add an example to read\_string/3. I will make a PR _soon_™.
