2018-08-09 (星期四)
查詢乙個流
操縱當前的流位置往往會很有用.或許是應用程式正在讀取乙個基於記錄的複雜檔案.需要來回跳躍;亦或是流需要被重新設成檔案位置零.無論是何種情況,標準i/o鏈結庫提供了一系列功能相當於lseek()系統呼叫的介面,例如,fseek()函式(最常見的標準i/o查詢介面)會根據offset與whence來操縱stream的檔案位置.
#include int fseek(file *stream, long offset, int whence);
如果whence的值被設為seek_set,則檔案位置會被設成offset;如果whence的值被設為seek_cur,則檔案位置會被設成當前位置加上offset;如果,whence的值被設為seek_end,則檔案位置被設成檔案末端加上offset.
執行成功時,fseek()會返回0,清除eof指示器並消除ungetc()所造成的影響(如果有的話);發生錯誤時,它返回-1並且將error設定為設定的值.最常見的錯誤是無效的流(ebadf)以及無效的whence引數(einval).
此外,標準i/o鏈結庫還提供了fsetpos():
#include int fsetpos(file *stream, fpos_t *pos);
此函式會講stream的流位置設定pos.它的功能如同將whence引數設為seek_set的fseek().執行成功時,它會返回0;否則,它會返回-1並且將errno設定成設定成適當的值.之所以提供此函式(以及它的反向操作fgetpos(), 稍後會提到),只是因為其他(非unix的)平台具體複雜的資料型別可以表示流位置.在其他平台上,如果c的long資料型別不夠使用,此函式是將流位置設成任意值的唯一方法.如果想讓你的linux應用程式移植到所有可能的平台,就不應該讓他們使用此介面,儘管他們可以這麼做.
標準i/o鏈結庫還提供了rewind()以作為乙個捷徑:
#include void rewind(file *stream);
如下的呼叫:
rewind(stream);
會將位置重新設定成流的開頭.除了還會清除錯誤指示器,它的功能如同:
fseek(stream, 0, seek_set);
注意,rewind()沒有返回值,因此無法直接傳達錯誤的情況.想確定發生錯誤的呼叫者,呼叫此函式之前就應該先清楚errno, 以便時候檢查此變數是否為非零值.例如:
errno = 0; rewind (stream);
if(errno)
/*錯誤
*/
巧妙複製乙個流
實際業務中可能出現重複消費乙個可讀流的情況,比如在前置過濾器解析請求體,拿到body進行相關許可權及身份認證 認證通過後框架或者後置過濾器再次解析請求體傳遞給業務上下文。因此,重複消費同乙個流的需求並不奇葩,這類似於js上下文中通過 deep clone乙個物件來操作這個物件副本,防止源資料被汙染。...
巧妙複製乙個流
實際業務中可能出現重複消費乙個可讀流的情況,比如在前置過濾器解析請求體,拿到body進行相關許可權及身份認證 認證通過後框架或者後置過濾器再次解析請求體傳遞給業務上下文。因此,重複消費同乙個流的需求並不奇葩,這類似於js上下文中通過 deep clone乙個物件來操作這個物件副本,防止源資料被汙染。...
巧妙複製乙個流
實際業務中可能出現重複消費乙個可讀流的情況,比如在前置過濾器解析請求體,拿到body進行相關許可權及身份認證 認證通過後框架或者後置過濾器再次解析請求體傳遞給業務上下文。因此,重複消費同乙個流的需求並不奇葩,這類似於js上下文中通過 deep clone乙個物件來操作這個物件副本,防止源資料被汙染。...