c/c++文件操作學習

c/c++文件操作學習

open函數

函數

int open(const char * pathname, int flags);
int open(const char * pathname, int flags, mode_t mode);

pathname:指路徑

flag 功能
O_RDONLY 以只讀方式打開文件
O_WRONLY 以只寫方式打開文件
O_RDWR 以可讀寫方式打開文件
上述三種旗標是互斥的, 也就是不可同時使用, 但可與下列的旗標利用OR運算符組合
O_CREAT 若欲打開的文件不存在則自動建立該文件
O_EXCL 如果O_CREAT 也被設置, 此指令會去檢查文件是否存在. 文件若不存在則建立該文件, 否則將導致打開文件錯誤. 此外, 若O_CREAT 與O_EXCL 同時設置, 並且欲打開的文件爲符號連接, 則會打開文件失敗
O_NOCTTY 如果欲打開的文件爲終端機設備時, 則不會將該終端機當成進程控制終端機
O_TRUNC 若文件存在並且以可寫的方式打開時, 此旗標會令文件長度清爲0, 而原來存於該文件的資料也會消失
O_APPEND 當讀寫文件時會從文件尾開始移動, 也就是所寫入的數據會以附加的方式加入到文件後面
O_NONBLOCK 以不可阻斷的方式打開文件, 也就是無論有無數據讀取或等待, 都會立即返回進程之中
O_NDELAY 同O_NONBLOCK
O_SYNC 以同步的方式打開文件
O_NOFOLLOW 如果參數pathname
O_DIRECTORY 如果參數pathname 所指的文件並非爲一目錄, 則會令打開文件失敗

參數mode 則有下列數種組合, 只有在建立新文件時纔會生效, 此外真正建文件時的權限會受到umask 值所影響, 因此該文件權限應該爲 (mode-umaks)

mode 權限
S_IRWXU00700 代表該文件所有者具有可讀、可寫及可執行的權限
S_IRUSR 或S_IREAD, 00400 代表該文件所有者具有可讀取的權限
S_IWUSR 或S_IWRITE, 00200 代表該文件所有者具有可寫入的權限
S_IXUSR 或S_IEXEC, 00100 代表該文件所有者具有可執行的權限
S_IRWXG 00070 代表該文件用戶組具有可讀、可寫及可執行的權限
S_IRGRP 00040 代表該文件用戶組具有可讀的權限
S_IWGRP 00020 代表該文件用戶組具有可寫入的權限
S_IXGRP 00010 代表該文件用戶組具有可執行的權限
S_IRWXO 00007 代表其他用戶具有可讀、可寫及可執行的權限
S_IROTH 00004 代表其他用戶具有可讀的權限
S_IWOTH 00002 代表其他用戶具有可寫入的權限
S_IXOTH 00001 代表其他用戶具有可執行的權限

錯誤代碼

參數 功能
EEXIST 參數pathname 所指的文件已存在, 卻使用了O_CREAT 和O_EXCL 旗標
EACCESS 參數pathname 所指的文件不符合所要求測試的權限
EROFS 欲測試寫入權限的文件存在於只讀文件系統內
EFAULT 參數pathname 指針超出可存取內存空間
EINVAL 參數mode 不正確
ENAMETOOLONG 參數 pathname 太長
ENOTDIR 參數pathname 不是目錄
ENOMEM 核心內存不足
ELOOP 參數pathname 有過多符號連接問題
EIO I/O 存取錯誤

mmap函數

頭文件

#include <unistd.h>    
#include <sys/mman.h>

函數

void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offsize);
//mmap()用來將某個文件內容映射到內存中,對該內存區域的存取即是直接對該文件內容的讀寫。

參數說明

參數 說明
start 指向欲對應的內存起始地址,通常設爲NULL,代表讓系統自動選定地址,對應成功後該地址會返回
length 代表將文件中多大的部分對應到內存
prot 代表映射區域的保護方式,有下列組合 PROT_EXEC:映射區域可被執行 PROT_READ :映射區域可被讀取PROT_WRITE:映射區域可被寫入PROT_NONE:映射區域不能存取
flags 會影響映射區域的各種特性:**MAP_FIXED **: 如果參數 start 所指的地址無法成功建立映射時,則放棄映射,不對地址做修正。通常不鼓勵用此旗標。**MAP_SHARED **: 對應射區域的寫入數據會複製迴文件內,而且允許其他映射該文件的進程共享。MAP_PRIVATE: 對應射區域的寫入操作會產生一個映射文件的複製,即私人的"寫入時複製" (copy on write)對此區域作的任何修改都不會寫回原來的文件內容。MAP_ANONYMOUS : 建立匿名映射,此時會忽略參數fd,不涉及文件,而且映射區域無法和其他進程共享。**MAP_DENYWRITE ** :只允許對應射區域的寫入操作,其他對文件直接寫入的操作將會被絕。MAP_LOCKED: 將映射區域鎖定住,這表示該區域不會被置換(swap)。在調用mmap()時必須要指定MAP_SHARED 或MAP_PRIVATE。
fd open()返回的文件描述詞,代表欲映射到內存的文件
offset 文件映射的偏移量,通常設置爲0,代表從文件最前方開始對應,offset必須是分頁大小的整數倍

返回值

若映射成功則返回映射區的內存起始地址,否則返回MAP_FAILED(-1),錯誤原因存於errno 中。返回值:若映射成功則返回映射區的內存起始地址,否則返回MAP_FAILED(-1),錯誤原因存於errno 中。
錯誤代碼:

代碼 功能
EBADF 參數fd 不是有效的文件描述詞
EACCES 存取權限有誤。如果是MAP_PRIVATE 情況下文件必須可讀,使用MAP_SHARED 則要有PROT_WRITE 以及該文件要能寫入
EINVAL 參數start、length 或offset 有一個不合法
EAGAIN 文件被鎖住,或是有太多內存被鎖住
ENOMEM 內存不足

使用中的問題

include <sys/types.h>                                                                         #include <sys/stat.h>                                                                          #include <fcntl.h>                                                                             #include <unistd.h>                                                                            #include <sys/mman.h>                                                                          #include <iostream>                                                                            using namespace std;                                                                           int main()
{                                                                           
	int fd;
	fd = open("Wandering.txt", O_RDWR | O_CREAT, 00777); 
	char* Out = (char*) mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
	close(fd);                                                   
	string He = "Hello World!";                                      
	char* str = (char*)&He;
	cout << &He << endl;                                          
	Out[1] = '1';                                              
	while(*str != '\0')                                                
	{                                                              
		cout << *str++ << endl;                                             
	}                                                       
	munmap(Out, 100); /* 解除映射 */                                                           }                                                                                                                                                                                       

當向mmap地址中寫入數據總是出現Bus error的提示
發生錯誤的原因是因爲mmap不能去擴展一個內容爲空的新文件,因爲大小爲0,所有本沒有與之對應的合法的物理頁,不能擴展。所以只需要在新創建的空文件中先寫入一些數據即可。

lseek()函數

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

函數調用

#include <unistd.h>
#include <sys/types.h>
off_t lseek(int filedes, off_t offset, int whence);

參數說明

返回值:

  • -1:失敗
  • 數據 新的偏移量
whence 功能
SEEK_SET 文件偏移量將被設置爲 offset
SEEK_CUR 文件偏移量將被設置爲 cfo 加上 offset
SEEK_END 文件偏移量將被設置爲文件長度加上 offset

SEEK_SET、SEEK_CUR 和 SEEK_END 是 System V 引入的,在這之前使用的是 0、1 和 2。

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