Skip to content

Commit d5284eb

Browse files
committed
read_exact and read_full
1 parent c7f633b commit d5284eb

File tree

1 file changed

+32
-25
lines changed

1 file changed

+32
-25
lines changed

text/0000-read-all.md

+32-25
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,66 @@
1-
- Feature Name: read_all
1+
- Feature Name: read_exact and read_full
22
- Start Date: 2015-03-15
33
- RFC PR: (leave this empty)
44
- Rust Issue: (leave this empty)
55

66
# Summary
77

88
Rust's Write trait has write_all, which attempts to write an entire
9-
buffer. This proposal adds read_all, which attempts to read a fixed
10-
number of bytes into a given buffer.
9+
buffer. This proposal adds two new methods, read_full and read_exact.
10+
read_full attempts to read a fixed number of bytes into a given
11+
buffer, and returns Ok(n) if it succeeds or in the event of EOF.
12+
read_exact attempts to read a fixed number of bytes into a given
13+
buffer, and returns Ok(n) if it succeeds and Err(ErrorKind::ShortRead)
14+
if it fails.
1115

1216
# Motivation
1317

14-
The new read_all method will allow programs to read from disk without
15-
having to write their own read loops. Most Rust programs which need
16-
to read from disk will prefer this to the plain read function. Many C
17-
programs have the same need, and solve it the same way (e.g. git has
18-
read_in_full). Here's one example of a Rust library doing this:
18+
The new read_exact method will allow programs to read from disk
19+
without having to write their own read loops to handle EINTR. Most
20+
Rust programs which need to read from disk will prefer this to the
21+
plain read function. Many C programs have the same need, and solve it
22+
the same way (e.g. git has read_in_full). Here's one example of a
23+
Rust library doing this:
1924
https://github.com/BurntSushi/byteorder/blob/master/src/new.rs#L184
2025

26+
The read_full method is useful the common case of implementing
27+
buffered reads from a file or socket. In this case, a short read due
28+
to EOF is an expected outcome, and the caller must check the number of
29+
bytes returned.
30+
2131
# Detailed design
2232

23-
The read_all function will take a mutable, borrowed slice of u8 to
33+
The read_full function will take a mutable, borrowed slice of u8 to
2434
read into, and will attempt to fill that entire slice with data.
2535

2636
It will loop, calling read() once per iteration and attempting to read
2737
the remaining amount of data. If read returns EINTR, the loop will
2838
retry. If there are no more bytes to read (as signalled by a return
29-
of Ok(0) from read()), a new error type, ErrorKind::ShortRead(usize),
30-
will be returned. ShortRead includes the number of bytes successfully
31-
read. In the event of another error, that error will be
39+
of Ok(0) from read()), the number of bytes read so far
40+
will be returned. In the event of another error, that error will be
3241
returned. After a read call returns having successfully read some
3342
bytes, the total number of bytes read will be updated. If that total
34-
is equal to the size of the buffer, read will return successfully.
43+
is equal to the size of the buffer, read_full will return successfully.
44+
45+
The read_exact method can be implemented in terms of read_full.
3546

3647
# Drawbacks
3748

3849
The major weakness of this API (shared with write_all) is that in the
3950
event of an error, there is no way to return the number of bytes that
40-
were successfully read before the error. But since that is the design
41-
of write_all, it makes sense to mimic that design decision for read_all.
51+
were successfully read before the error. But returning that data
52+
would require a much more complicated return type, as well as
53+
requiring more work on the part of callers.
4254

4355
# Alternatives
4456

4557
One alternative design would return some new kind of Result which
4658
could report the number of bytes sucessfully read before an error.
47-
This would be inconsistent with write_all, but arguably more correct.
48-
49-
If we wanted io::ErrorKind to be a smaller type, ErrorKind::ShortRead
50-
could be unparameterized. But this would reduce the information
51-
available to calleres.
5259

53-
Finally, in the event of a short read, we could return Ok(number of
54-
bytes read before EOF) instead of an error. But then every user would
55-
have to check for this case. And it would be inconsistent with
56-
write_all.
60+
If we wanted one method instead of two, ErrorKind::ShortRead could be
61+
parameterized with the number of bytes read before EOF. But this
62+
would increase the size of ErrorKind.
5763

5864
Or we could leave this out, and let every Rust user write their own
59-
read_all function -- like savages.
65+
read_full or read_exact function, or import a crate of stuff just for
66+
this one function.

0 commit comments

Comments
 (0)