What are the advantages of pwrite
and pread
over fwrite
and fread
?

- 5,716
- 8
- 28
- 43

- 2,653
- 8
- 31
- 50
-
Possible duplicate of [What is the difference between read and pread in unix?](https://stackoverflow.com/questions/1687275/what-is-the-difference-between-read-and-pread-in-unix) – Ciro Santilli OurBigBook.com Jul 15 '17 at 10:26
4 Answers
There are two parts:
Difference between
pread
/pwrite
andread
/write
:They are both at the same level, namely system calls. There are two differences:
- The "p" variants take offset to read from, so they are independent of the current file pointer. That makes it easier to read/write from multiple threads concurrently.
- The "p" variants only work on seekable files (i.e. real files, not pipes, sockets or devices).
Difference between
read
/pread
/write
/pwrite
andfread
/fwrite
:The "f" variants are standard runtime wrappers of the former (using the basic variants). They support in-process buffering. That can significantly improve performance for simple code, but it makes use of other features of the system-call level impractical.
Only use the "p" variants if you have good use for reading at random offsets (avoiding seeks and allowing concurrent access via one file handle), which often the case with some kind of database files (record-oriented with records at known offsets) and rarely in other applications.

- 73,652
- 13
- 125
- 172
-
Huh? I don't see any support for scatter-gather in pread()/pwrite(). Perhaps you meant readv()/writev()? Some systems like Linux and some BSD variants have "combination" syscalls preadv()/pwritev() but that's not part of POSIX yet. – janneb Sep 29 '11 at 06:49
-
@janneb: Hm, right. I misremembered something and didn't actually read the man page through, though I did open it. – Jan Hudec Sep 29 '11 at 07:10
-
Hey but how do I get the file discriptor.... When I fopen it returns to me a file pointer, then how can I get a int file discriptor??? – Invictus Sep 29 '11 at 11:33
-
@Invictus: Use `open` with `read`, `write`, `pread` and `pwrite` and use `fopen` with `fread`, `fwrite` and `fprintf`. They are different level of interface and don't mix well (there are functions to convert one kind of file to the other, but you have to really understand how the stdio layer works before using them). – Jan Hudec Sep 29 '11 at 11:55
-
Doesn't pread have buffering support? I think the kernel is doing some kind of cache/buffer for File IO unless you use O_DIRECT to open a file. Isn't it? – Steinway Wu Nov 10 '12 at 06:42
-
@SteinwayWu: The kernel does a lot of caching unless `O_DIRECT` is passed indeed. However kernel entry/exit still incurs noticeable penalty, so if you are reading one byte at a time, the `f`* functions will be significantly faster. That's why functions like `fscanf`, `fgets` or `fprintf` that need to process each character before proceeding to the next only exist in the buffered interface. Unfortunately some other functions like `select`/`poll` only exist in the unbuffered one, so you have to select appropriate interface in each case. – Jan Hudec Nov 10 '12 at 09:19
-
@JanHudec, oh yes. And I think that's why you said "in-process" buffering. I get it now. Thanks! – Steinway Wu Nov 11 '12 at 18:53
It's useful when you do a lot of random read/write operations. There is even an option for SQLite3 that replaces seek()
+ read()
and seek()
+ write()
with pread()/pwrite()
.
The advantage: seek()
+ read()
and seek()
+ write()
both are the pairs of system calls while pread()
and pwrite()
are single system calls. It's usually an universal truth that the less system calls program issues the more efficient it is.

- 7,191
- 2
- 34
- 64
-
Hey but how do I get the file discriptor.... When I fopen it returns to me a file pointer, then how can I get a int file discriptor??? – Invictus Sep 29 '11 at 11:25
-
pread/pwrite are POSIX system calls(eg Linux, FreeBSD...). they are working with UNIX file descriptors that are ints. you can get one by using open() syscall(function). look at http://linux.die.net/man/2/pwrite – GreenScape Sep 29 '11 at 13:12
-
1@Invictus: `FILE*` can be converted to the raw `int` `fd` with [`fileno(3)`](https://linux.die.net/man/3/fileno) if you want to use `fopen` but sometimes use the underlying `fd` with the low level system calls. Note that the low level system calls don't see the user space buffering of `stdio` `FILE*` objects, so you could have problems if the user space buffer says one thing, and you bypass it with direct `write`/`pwrite`/`read`/`pread` calls. – ShadowRanger Oct 13 '16 at 23:12
Current file position doesn't change after a call to pread
/pwrite
.
Also because you don't need to call lseek
to change the current file position pread
/pwrite
avoid potential race conditions when multiple threads are involved.

- 519
- 5
- 6
Just one minor bit of info missing here. pread and pwrite are atomic operations for lseek+read() and lseek+write(). main usage is to guarantee no kernel interrupts between lseek+read() and lseek+write() which is useful if two processes have the same file opened

- 326
- 5
- 14