linux高級編程之文件操作:
1、perror(const char* msg); 用於產生一條基於其參數字符串的錯誤信息,錯誤格式是:msg指向的字符串,冒號,錯誤消息,換行符;
2、linux文件種類:普通文件,目錄文件,鏈接文件,設備文件;
3、一個進程啓動時,會自動打開三個流:標準輸入流,標準輸出流,標準錯誤處理流;對應的文件描述符是0、1、2,分別用宏 STDIN_FILENO 、STDOUT_FILENO 、STDERR_FILENO替換;
4、文件描述符的範圍在0--OPEN_MAX(在linux中,最大是1048576);
5、函數open(const char *pathname, int flags, mode_t mode)
參數:pathname :要打開文件的路徑;
flag : 打開的方式:只讀,只寫,讀寫必須選擇其中一個,其他可以進行或運算,如追加,不存在則創建,截斷爲0,非阻塞方式打開;
mode: 指定打開該文件時使用的權限;
6、函數read(int filedes,void *buff,size_t nbytes);
從當前文件偏移量開始,讀取指定大小的內容到buff中;返回實際讀到的字節數,出錯返回-1,讀到文件末尾,返回0;
note:注意在這裏讀寫的時候,如果buff只是一個指針變量,則不能使用sizeof()來確定讀數據的大小,因爲使用一個sizeof()來測量一個指針,只能返回指針本身的大小,而不是指針指向空間的大小,如果是指向的是字符串,則應該使用strlen() ,如果是其他類型,則應該視情況而定;
7、函數write(int filedes,const void *buff,size_t nbyte);
從當前文件偏移量開始,把buff中的nbyte數據寫入到打開的文件中,返回實際寫入的參數,如果返回值和nbyte相同,則表示寫入正確,否則寫入錯誤;寫入錯誤的原因之一可能是磁盤已滿;
8、常規文件讀寫不會出現阻塞現象,但是從終端讀寫或者從網絡讀寫,則可能出現阻塞的現象,如果open()一個設備時指定了非阻塞(O_NONBLOCK),則read 和 write 就不會出現阻塞的現象;
9、非阻塞工作模式:
while(1)
{
非阻塞讀 read(設備1);
if(設備1有數據到達)
{
處理數據;
}
非阻塞讀 read(設備2);
if(設備2有數據到達)
{
處理數據;
}
}
10、函數 offset lseek(int filesdes ,off_t offset, int whence)
作用,指定文件操作指針的偏移量;
offset: 偏移量的大小;
whence : 偏移的起始點;
SEEK_SET 表示從文件開始處偏移offset個字節,
SEEK_CUR 表示從當前位置開始偏移offset個字節;
SEEK_END 表示將文件的偏移量設置爲文件長度加offset,offset可正可負;
返回值:返回文件操作指針相對於文件起始位置的偏移量的大小;
可以使用 x = lseek(fd,0,SEEK_CUR)確定當前文件的偏移量大小;
打開文件時使用了O_APPEND,則文件指針會移動到文件末尾輸入;
如果需要創建一個大文件,可以使用lseek()將文件指針偏移很大的值,然後在最後,寫入字符,表示文件結束,那麼這就創建了一個佔有空間很大的一個文件;
11、fcntl作用:改變訪問屬性,但是不改變其本身屬性;
12、ioctl() 作用,向設備發送指令;可以讀取一些數據,但這些數據不能被read 或者 write 操作,ioctl操作的是控制信息,屬於帶外數據(out-of-band),write 操作的是帶內數據(in-band);
13、使用mmap(void *addr,size_t len, int prot, int flag, int filedes, off_t off);
這個函數可以將硬盤上的一部分空間映射到內存上,對內存操作,就相當於對硬盤操作,而不用再使用write 和read 函數;直接使用指針即可對文件進行操作;
返回值:映射空間的起始地址,不一定是addr,但是一定在指定的addr之上;
addr: 用戶指定的映射空間地址,但實際上,不一定從這個地址開始映射;如果參數爲NULL,則表示由系統選擇映射的起始地址;
prot:: 表明映射空間對磁盤的讀寫以及可執行權限的使能情況,
flag ; 表明了共享權限;MAP_SHARED_表示各個進程共享,可以修改;
MAP_PRIVATE 表示對各個進程表現私有,其他進程對共享空間的修改,都不會影響到磁盤文件;
int filedes :表明要映射到內存的磁盤文件的文件描述符;
off : 表示從磁盤文件的off偏移量開始映射;
14、可以使用munmap(void *addr,size_t len)釋放映射空間;
15、truncate(const char* path, off_t length) 和 ftruncate(int fd, off_t length) 用於截取文件的一部分,如果length大於文件長度,則會將文件擴展到length大小,多出的空間每位用0表示;
截斷並不是將被丟棄的文件擦除,而是規定了文件的作用域小了;
16、int fsync(int filedes) 把指定文件的數據和屬性都寫入磁盤;
int fdatasync(int filedes) 把指定文件的數據部分寫到磁盤;
void sync(void) 把修改部分排入磁盤寫隊列,準備寫入磁盤;