lseek

lseek

lseek函式(隨機訪問檔案) 使用UNIX系統調用來讀取檔案內容時,系統究竟是從檔案的哪一個位置讀取數據,完全由檔案指針決定。例如:剛開始讀取數據時,檔案指針通常是指向檔案的起始位置。

基本信息

簡介

函式名: lseek

頭檔案:#include <sys/types.h> #include <unistd.h>

用 法: off_t lseek(int handle, off_t offset, int fromwhere);

所有打開的檔案都有一個當前檔案偏移量(current file offset),以下簡稱為 cfo。cfo 通常是一個非負整數,用於表明檔案開始處到檔案當前位置的位元組數。讀寫操作通常開始於 cfo,並且使 cfo 增大,增量為讀寫的位元組數。檔案被打開時,cfo 會被初始化為 0,除非使用了 O_APPEND 。

使用 lseek 函式可以改變檔案的 cfo 。

lseek 的以下用法返回當前的偏移量:

off_t currpos;

currpos = lseek(fd, 0, SEEK_CUR);

這個技巧也可用於判斷我們是否可以改變某個檔案的偏移量。如果參數 fd(檔案描述符)指定的是 pipe(管道)、FIFO 或者 socket,lseek 返回 -1 並且置 errno 為 ESPIPE。

對於普通檔案(regular file),cfo 是一個非負整數。但對於特殊設備,cfo 有可能是負數。因此,我們不能簡單地測試 lseek 的返回值是否小於 0 來判斷 lseek 成功與否,而應該測試 lseek 的返回值是否等於 -1 來判斷 lseek 成功與否。

lseek 僅將 cfo 保存於核心中,不會導致任何 I/O 操作。這個 cfo 將被用於之後的讀寫操作。

如果 offset 比檔案的當前長度更大,下一個寫操作就會把檔案“撐大(extend)”。這就是所謂的在檔案里創造“空洞(hole)”。沒有被實際寫入檔案的所有位元組由重複的 0 表示。空洞是否占用硬碟空間是由檔案系統(file system)決定的。

#include<stdio.h>

#include<string.h>

#include<sys/stat.h>

#include<fcntl.h>

int main()

{

int handle;

char msg[]="This is a test";

char ch;

/*create a file*/

handle=open("TEST.$$$",O_CREAT|O_RDWR,S_IREAD|S_IWRITE);

/*write some data to the file*/

write(handle,msg,strlen(msg));//檔案中寫入字元串,即This is a test

/*seek to the begining of the file*/

lseek(handle,0,SEEK_SET);//重定向到檔案開始

/*reads chars from the file until we hit EOF*/

while(read(handle,&ch,1) > 0)//!=EOF和>=0都不行 read函式返回的是實際讀取字元的位數

{

printf("%c",ch);

}

close(handle);

return 0;

}

Linux C

相關函式

dup,open,fseek

表頭檔案

#include<sys/types.h>

#include<unistd.h>

定義函式

off_t lseek(int filde,off_t offset ,int whence);

函式說明

每一個已打開的檔案都有一個讀寫位置,當打開檔案時通常其讀寫位置是指向檔案開頭,若是以附加的方式打開檔案(如O_APPEND),則讀寫位置會指向檔案尾。當read()或write()時,讀寫位置會隨之增加,lseek()便是用來控制該檔案的讀寫位置。參數fildes 為已打開的檔案描述詞,參數offset 為根據參數whence來移動讀寫位置的位移數。

Offset:偏移量,每一讀寫操作所需要移動的距離,單位是位元組的數量,可正可負(向前移,向後移)。

參數

whence為下列其中一種:(SEEK_SET,SEEK_CUR和SEEK_END和依次為0,1和2).

SEEK_SET 將讀寫位置指向檔案頭後再增加offset個位移量。

SEEK_CUR 以目前的讀寫位置往後增加offset個位移量。

SEEK_END 將讀寫位置指向檔案尾後再增加offset個位移量。

當whence 值為SEEK_CUR 或SEEK_END時,參數offet允許負值的出現。

下列是較特別的使用方式:

1) 欲將讀寫位置移到檔案開頭時:

lseek(int fildes,0,SEEK_SET);

2) 欲將讀寫位置移到檔案尾時:

lseek(int fildes,0,SEEK_END);

3) 想要取得目前檔案位置時:

lseek(int fildes,0,SEEK_CUR);

返回值

當調用成功時則返回目前的讀寫位置,也就是距離檔案開頭多少個位元組。若有錯誤則返回-1,errno 會存放錯誤代碼。

可能設定erron的錯誤代碼:

EBADF: fildes不是一個打開的檔案描述符。

ESPIPE:檔案描述符被分配到一個管道、套接字或FIFO。

EINVAL:whence取值不當。

附加說明

Linux系統不允許lseek()對tty裝置作用,此項動作會令lseek()返回ESPIPE。

SEEK_SET 等同於數字0 例如 :lseek(int fildes,0,SEEK_SET);=lseek(int fildes,0,0);

SEEK_CUR 等同於數字1 例如 :lseek(int fildes,0,SEEK_CUR);=lseek(int fildes,0,1);

SEEK_END 等同於數字2 例如 :lseek(int fildes,0,SEEK_END);=lseek(int fildes,0,2);

相關詞條

相關搜尋

熱門詞條

聯絡我們