pread,pwrite,read,write區別

2puT發表於2016-07-10

pread, pwrite


<code class="language-c++ hljs vala has-numbering"><span class="hljs-preprocessor">#include <unistd.h></span>

<span class="hljs-comment">// 返回值: 讀到的位元組數,若已到檔案結尾則返回0,若出錯返回-1</span>
ssize_t pread(<span class="hljs-keyword">int</span> filedes, <span class="hljs-keyword">void</span> *buf, size_t nbytes, off_t offset);

<span class="hljs-comment">// 返回值: 若成功返回已寫的位元組數,若出錯返回-1</span>
ssize_t pwrite(<span class="hljs-keyword">int</span> filedes, <span class="hljs-keyword">const</span> <span class="hljs-keyword">void</span> *buf, size_t nbytes, off_t offset);</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul>

呼叫pread相當於順序呼叫lseek和read,但pread和這種呼叫又有重大區別:

  • 呼叫pthread時,無法中斷其定位和讀操作
  • 不更新檔案指標

呼叫pwrite相當於呼叫lseek和write,但也與它們有類似區別。

read, write


<code class="language-c++ hljs vala has-numbering"><span class="hljs-preprocessor">#include<unistd.h></span>
<span class="hljs-comment">// 成功:返回讀到的位元組數;出錯:返回-1;檔案尾:返回0;</span>
ssize_t read (<span class="hljs-keyword">int</span> filedes, <span class="hljs-keyword">void</span> *buf, size_t nbytes );</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul>
  • 當從普通檔案讀時,在讀到要求位元組數之前已到達了檔案尾端。

  • 當從終端裝置讀時,通常一次最多讀一行。

  • 當從網路讀時,網路中緩衝機構可能造成返回值小於所要求讀的位元組數。
  • 當從管道或FIFO讀時,如若管道包含的位元組少於所需的數量,那麼只返回實際用的位元組數。
  • 當從某些面向記錄的裝置讀時,一次最多返回一個記錄。
  • 當某一訊號造成中斷,而已經讀了部分資料量時。
  • 讀操作從檔案的當前偏移量處開始,在成功返回之前,該偏移量將增加實際讀到的位元組數。
<code class="language-c++ hljs vala has-numbering"><span class="hljs-preprocessor">#include<unistd.h></span>

<span class="hljs-comment">// 成功:返回已寫的位元組數;出錯:返回-1;</span>
ssize_t write (<span class="hljs-keyword">int</span> filedes, <span class="hljs-keyword">const</span> <span class="hljs-keyword">void</span> *buf, size_t nbytes );</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul>
  • 對於普通檔案,寫操作從檔案的當前偏移量處開始
  • 如果在開啟該檔案時,指定了O_APPEND選項,則在每次寫操作之前,將檔案偏移量設定在檔案的當前結尾處
  • 在一次成功寫之後,該檔案偏移量增加實際寫的位元組數

總結:

  • 因為歷史上有些系統不支援O_APPEND,才定義了pread和pwrite。

  • 因為lseek與read之間,可能會出現非預期的效果,所以定義pread。

  • 隨機訪問的話,pread/pwrite比較方便。

相關文章