UNIX系統檔案IO函式
阿新 • • 發佈:2019-01-26
在一開始接觸到Linux的時候,我們經常接觸到的系統IO函式有下列這幾個
open()函式,write()函式,read()函式,lseek()函式,close()函式下面我們將逐個探究一下:open函式: 開啟或建立一個檔案
庫和函式原型:
#include<fcntl.h>
int open(const char* pathname,int flag, ... /*mode_t mode*/)我們將第三個引數寫為...,是因為ISO C用這種方法表明餘下的引數機器型別將根據具體的呼叫有所不同。
對於open函式,只有在建立新檔案的時候才會使用到第三個引數。
解析:返回值:
成功返回一個整型(int)的檔案描述符,這個檔案描述符可以看作是一個開啟檔案的鑰匙,凡是對檔案的操作都離不開它。
錯誤返回-1
這個檔案描述符一定是用最小的未使用的描述符數值,其中0,1,2分別是標準輸入stdin,標準輸出stdout和標準出錯輸出stderr ,所以我們在不修改或者關閉其中三個的情況下,打印出的第一個描述符數值一般是3引數:
pathname:要開啟或者建立的檔名。
flag :開啟方式的選項,用下來一個或多個常量進行或|運算構成的flag引數。
選項:O_RDONLY, O_WRONLY, O_RDWR 這三個常量必須有且只能選一個
O_CREAT:檔案不存在則建立
O_TRUNC:若檔案存在,則把資料清零。
上面這幾個是常用到的,其它的選項可以自行man瞭解。
這幾個常量對應數值O_RDONLY----0, O_WRONLY----1, O_RDWR----2, O_CREAT----4
使用它們 注意進行或|運算之後的結果。mode:它其實是一個8進位制數,說明你將要建立檔案的許可權
例:0777則代表-rwxrwxrwxwrite函式:往開啟的檔案裡面寫資料 庫和函式原型:
#include <unistd.h>ssize_t write(int fd, const void *buf, size_t count);解析:
返回值:成功則返回已寫的位元組數,錯誤返回-1fd: open函式返回的檔案描述符
buf: 要寫入資料的地址,通常是已宣告的字串的首地址
count:一次要寫幾個位元組,通常為strlen()個
程式碼塊:
執行結果截圖:
read函式: 從開啟的裝置或檔案中讀取資料。
庫和函式原型:
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
返回值:成功返回讀取的位元組數,出錯返回-1並設定errno,0表示檔案末端
如果在調read之前已到達檔案末尾,則這次read返回0
如果要求讀100個位元組,而離檔案末尾只有99個位元組,則read返回99,下一次再呼叫read返回0
引數: 可聯絡write函式記憶
fd: 檔案描述符
buf: 要讀資料的地址,通常是已宣告的字串的首地址
count 一次要讀多少個數據
舉個例子:在終端讀入並寫出
lseek函式: 顯式地為一個開啟的檔案設定偏移量,通常讀寫操作都是從當前檔案偏移量處開始的,並使偏移量增加所讀寫的位元組數庫和函式原型:#include <unistd.h>
#include <sys/types.h>off_t lseek(int fd, off_t offset, int whence);返回值:成功返回新的檔案偏移量注意可能負數,出錯返回-1
如果檔案 描述符引用的是一個管道,FIFO或者 網路套接字,則lseek返回-1,,並將error設定成ESPIPE引數:
fd: 檔案描述符
offset 的含義取決於引數 whence
whence有三個選項:
1. 如果 whence 是 SEEK_SET, 檔案偏移量將被設定為 0加上 offset。
2. 如果 whence 是 SEEK_CUR,檔案偏移量將被設定為 當前值 加上 offset,offset 可以為正也可以為負。
3. 如果 whence 是 SEEK_END,檔案偏移量將被設定為檔案長度加上 offset,offset 可以為正也可以為負。注意:
lseek 僅將檔案偏移量保存於核心中,不會導致任何 I/O 操作。這個檔案偏移量將被用於之後的讀寫操作。檔案偏移量可以大於當前檔案長度,在這之上,對檔案的下一次寫操作就會在檔案中(原始檔末端到新開始的位置)構成空洞,並被讀成0,且檔案中的空洞並不佔用磁碟的記憶體空間。程式碼塊:
close(fd)函式: 關閉這個已開啟的檔案,這個就沒什麼好說的了吧。。。上面大概就是我在學習系統IO函式的時候的一點小結,其實就是把握好這個檔案描述符就好了,引數這個東西用多了就熟練了。。
open()函式,write()函式,read()函式,lseek()函式,close()函式下面我們將逐個探究一下:open函式: 開啟或建立一個檔案
庫和函式原型:
#include<fcntl.h>
int open(const char* pathname,int flag, ... /*mode_t mode*/)我們將第三個引數寫為...,是因為ISO C用這種方法表明餘下的引數機器型別將根據具體的呼叫有所不同。
對於open函式,只有在建立新檔案的時候才會使用到第三個引數。
解析:返回值:
成功返回一個整型(int)的檔案描述符,這個檔案描述符可以看作是一個開啟檔案的鑰匙,凡是對檔案的操作都離不開它。
錯誤返回-1
這個檔案描述符一定是用最小的未使用的描述符數值,其中0,1,2分別是標準輸入stdin,標準輸出stdout和標準出錯輸出stderr
pathname:要開啟或者建立的檔名。
flag :開啟方式的選項,用下來一個或多個常量進行或|運算構成的flag引數。
選項:O_RDONLY, O_WRONLY, O_RDWR 這三個常量必須有且只能選一個
O_CREAT:檔案不存在則建立
O_TRUNC:若檔案存在,則把資料清零。
上面這幾個是常用到的,其它的選項可以自行man瞭解。
這幾個常量對應數值O_RDONLY----0, O_WRONLY----1, O_RDWR----2, O_CREAT----4
使用它們 注意進行或|運算之後的結果。mode:它其實是一個8進位制數,說明你將要建立檔案的許可權
例:0777則代表-rwxrwxrwxwrite函式:往開啟的檔案裡面寫資料
#include <unistd.h>ssize_t write(int fd, const void *buf, size_t count);解析:
返回值:成功則返回已寫的位元組數,錯誤返回-1fd: open函式返回的檔案描述符
buf: 要寫入資料的地址,通常是已宣告的字串的首地址
count:一次要寫幾個位元組,通常為strlen()個
程式碼塊:
#include<unistd.h> #include<sys/types.h> #include<fcntl.h> #include<string.h> #include<stdio.h> #include<sys/stat.h> int main() { int fd=open("./log",O_WRONLY|O_CREAT,775);//以只寫的形式建立mylog if(fd==-1) { perror("open fail!\n"); return -1; } const char*msg="Hello Koma\n"; int i=0; while(i<10) { write(fd,msg,strlen(msg)); i++; } printf("%s\n",msg); close(fd); }
執行結果截圖:
read函式: 從開啟的裝置或檔案中讀取資料。
庫和函式原型:
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
返回值:成功返回讀取的位元組數,出錯返回-1並設定errno,0表示檔案末端
如果在調read之前已到達檔案末尾,則這次read返回0
如果要求讀100個位元組,而離檔案末尾只有99個位元組,則read返回99,下一次再呼叫read返回0
引數: 可聯絡write函式記憶
fd: 檔案描述符
buf: 要讀資料的地址,通常是已宣告的字串的首地址
count 一次要讀多少個數據
舉個例子:在終端讀入並寫出
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
char*buf[10];
size_t st=read(STDIN_FILENO,buf,10);//STDIN標準輸入
if(st<0)
{
printf("read fail!\n");
}
write(STDOUT_FILENO,buf,st);//標準輸出
printf("\n");
return 0;
}
執行結果:lseek函式: 顯式地為一個開啟的檔案設定偏移量,通常讀寫操作都是從當前檔案偏移量處開始的,並使偏移量增加所讀寫的位元組數庫和函式原型:#include <unistd.h>
#include <sys/types.h>off_t lseek(int fd, off_t offset, int whence);返回值:成功返回新的檔案偏移量注意可能負數,出錯返回-1
如果檔案 描述符引用的是一個管道,FIFO或者 網路套接字,則lseek返回-1,,並將error設定成ESPIPE引數:
fd: 檔案描述符
offset 的含義取決於引數 whence
whence有三個選項:
1. 如果 whence 是 SEEK_SET, 檔案偏移量將被設定為 0加上 offset。
2. 如果 whence 是 SEEK_CUR,檔案偏移量將被設定為 當前值 加上 offset,offset 可以為正也可以為負。
3. 如果 whence 是 SEEK_END,檔案偏移量將被設定為檔案長度加上 offset,offset 可以為正也可以為負。注意:
lseek 僅將檔案偏移量保存於核心中,不會導致任何 I/O 操作。這個檔案偏移量將被用於之後的讀寫操作。檔案偏移量可以大於當前檔案長度,在這之上,對檔案的下一次寫操作就會在檔案中(原始檔末端到新開始的位置)構成空洞,並被讀成0,且檔案中的空洞並不佔用磁碟的記憶體空間。程式碼塊:
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
int fd=open("./fish",O_RDWR|O_CREAT,0777);
if(fd<0)
{
perror("open");
printf("open fail!");
return -1;
}
char msg[100] = "this is msg\n";
write(STDOUT_FILENO,msg,strlen(msg));//在標準輸出視窗寫資料
write(fd,msg,12);//在新建立的fish裡面寫資料
lseek(fd, 0,SEEK_SET);//把偏移量設定成0,要是把0換成strlen(msg)-->r=0;
int r = read(fd,msg,100);//從開始出開始讀資料
printf("r=%d\n", r);
close(fd);
return 0;
}
執行結果:
close(fd)函式: 關閉這個已開啟的檔案,這個就沒什麼好說的了吧。。。上面大概就是我在學習系統IO函式的時候的一點小結,其實就是把握好這個檔案描述符就好了,引數這個東西用多了就熟練了。。