Unix系統編程()lseek系統調用

原文鏈接:https://www.cnblogs.com/tuhooo/p/8641991.html

之前知道lseek這個系統調用可以改變文件的偏移量,或者叫偏移量或指針。

文件偏移量是指執行下一個read或者write操作的文件起始位置,會以相對於文件頭部起始點的文件當前位置來表示。

除非指定了O_APPEND選項。

文件第一個字節的偏移量爲0。

文件打開時,會將文件偏移量設置爲指向文件的開始,以後每次read或write調用將自動對其進行調整,以指向已讀或已寫數據後的下一字節。因此連續的read和write調用將按順序遞進,對文件進行操作。

lseek會根據offset和whence參數值來調整文件的偏移量。

off_t lseek(int fd, off_t offset, int whence)

offset 指定了一個以字節爲單位的數值

whence 表明應參照哪個基點來解釋offset參數,應爲下列其中之一:

SEEK_SET 將文件偏移量設置爲文件頭部起始點開始的offset字節

SEEK_CUR 相對於當前文件偏移量,將文件偏移量調整offset個字節

SEEK_END 將文件偏移量設置爲起始於文件尾部的offset個字節,也就是offset應該從文件最後一個字節之後的下一個字節算起。

image

早期的UNIX實現中,whence參數用整數0,1,2來表示的。

如果whence參數值爲SEEK_CUR或者SEEK_END,那麼offset參數可以爲正數也可以爲負數;如果whence參數值爲SEEK_SET,offset參數值必須爲非負數。

lseek調用成功會返回新的文件偏移量,下面調用只是獲取文件偏移量的當前位置,並沒有修改它。

curr = lseek(fd, 0, SEEK_CUR);

lseek(fd, 0, SEEK_SET);         start of file

lseek(fd, 0, SEEK_END);        Next byte after the end of the file

lseek(fd, –1, SEEK_END);      Last byte of file

lseek(fd, –10, SEEK_CUR);    Ten bytes prior to current location

lseek(fd, 10000, SEEK_END);   10001 bytes past last byte of file

lseek調用只是調整內核中與文件描述符相關的文件偏移量記錄,並沒有引起對任何物理設備的訪問。

文件偏移量,文件描述符和已打開文件的關係還需要進一步釐清。

lseek並不適用於所有類型的文件,不允許將lseek應用於管道、FIFO、socket或者終端。

一旦如此,調用將會失敗,並將errno置爲ESPIPE。

另一方面,只要合情合理,也可以將lseek應用於設備,例如磁盤或者磁帶上的某一具體位置。

lseek的l來源於long。

 

lseek和文件空洞。

文件偏移量可以大於文件的當前長度的,在這種情況下,該文件的下一次寫將加長該文件,並在文件中構成一個空洞,這一點是允許的。位於文件中但沒有寫過的字節都被讀爲0。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
char buf1[] = "abcdefghij";
char buf2[] = "ABCDEFGHIJ";

int main(int argc, char * argv[]) {

  int fd;
  if( (fd = creat("file.hole", FILE_MODE)) < 0)
    fprintf(stderr, "creat error\n");

  if( write(fd, buf1, 10) != 10)
    fprintf(stderr, "buf1 write error\n");

  if( lseek(fd, 16384, SEEK_SET) == -1)
    fprintf(stderr, "lseek error\n");

  if( write(fd, buf2, 10) != 10)
    fprintf(stderr, "buf2 write error\n");

  exit(0);
}

文件中的空洞並不要求在磁盤上佔用存儲區。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章