C語言檔案與目錄(二)

loophome發表於2015-11-03

檔案的開啟指的是從磁碟中找到一個檔案,返回一個整型的開啟檔案順序編號。開啟的檔案處於可讀可寫狀態。檔案的關閉指的是釋放開啟的檔案,使檔案處於不可讀寫的狀態。 

開啟檔案函式open:函式open的作用是開啟一個檔案,使檔案處於可讀寫的狀態。這個函式的使用方法如下所示。

int open(char *pathname, int flags);

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

檔案開啟方式的設定:在上一小節所示函式的引數列表中,pathname表示要開啟檔案的路徑字串。引數flags是系統定義的一些整型常數,表示檔案的開啟方式。Flags的可選值如下所示。

O_RDONLY:以只讀方式開啟檔案。
O_WRONLY:以只寫方式開啟檔案。
O_RDWR:以可讀寫方式開啟檔案。

上述三種旗標是互斥的,也就是不可同時使用,但可與下列的旗標利用“|”運算子組合。

O_CREAT:若要開啟的檔案不存在則自動建立該檔案。
O_EXCL:如果O_CREAT 已被設定,此指令會去檢查檔案是否存在。檔案若不存在則建立該檔案,否則將導致開啟檔案錯誤。此外,若O_CREAT與O_EXCL同時設定時,如果要開啟的檔案為一個連結,則會開啟失敗。
O_NOCTTY:如果要開啟的檔案為終端機裝置時,則不會將該終端機當成程式控制終端機。
O_TRUNC:若檔案存在並且以可寫的方式開啟時,此標誌會清空檔案。這樣原來的檔案內容會丟失。
O_APPEND:以附加的檔案開啟檔案。當讀寫檔案時會從檔案尾開始向前移動,寫入的資料會以附加的方式加入到檔案後面。
O_NONBLOCK:以不可阻斷的方式開啟檔案,也就是無論有無資料讀取或等待,都會立即結束檔案的開啟。
O_NDELAY:O_NONBLOCK。
O_SYNC:以同步的方式開啟檔案,所有的檔案操作不寫入到快取。
O_NOFOLLOW:如果引數pathname 所指的檔案為一符號連線,則會開啟失敗。
O_DIRECTORY:如果引數pathname 所指的檔案的目錄不存在,則開啟檔案失敗。

開啟檔案的許可權:開啟檔案時,如果沒有這個檔案則會自動新建一個檔案。在新建檔案時需要設定新建檔案許可權。系統為引數mode定義了下面這些常數,可以直接使用這些常數來設定檔案的許可權。這些許可權設定只有在建立新檔案時才會有效。 
S_IRWXU:00700許可權,該檔案所有者具有可讀可寫可執行的許可權。
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 許可權,其他使用者具有可執行的許可權。

檔案開啟例項:本小節講解一個檔案開啟例項,用open函式開啟一個檔案。呼叫這個函式時,如果正確的開啟了這個檔案,則返回這個檔案的開啟編號。如果開啟失敗則返回0。使用這個函式之前需要在程式的最前面包含下面這些標頭檔案。
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
open函式可能發生下面這些錯誤。可用errno捕獲開啟檔案時發生的錯誤。
EEXIST:引數pathname 所指的檔案已存在,卻使用了O_CREAT和O_EXCL旗標。
EACCESS:引數pathname所指的檔案沒有開啟許可權。
EROFS:欲寫入許可權的檔案存在於只讀檔案系統內。
EFAULT:引數pathname指標超出可存取記憶體空間。
EINVAL:引數mode不正確。
ENAMETOOLONG:引數pathname太長。
ENOTDIR:引數pathname不在一個目錄中。
ENOMEM:核心記憶體不足。
ELOOP:引數pathname有過多符號連線問題。
EIO:I/O存取錯誤。

關閉檔案函式close:函式close的作用是關閉一個已經開啟的檔案。使用完檔案後需要則可使用close函式關閉該檔案,這個操作會讓資料寫回磁碟,並釋放該檔案所佔用的資源。該函式的使用方法如下所示。
int close(int fd);

引數fd是用open函式開啟檔案時返回的開啟序號。如果成功關閉檔案則返回0,發生錯誤則返回-1。在程式結束時,系統會自動關閉已開啟的檔案,但仍建議在程式中關閉檔案,並檢查返回值是否正確。在關閉檔案時,可能返回EBADF錯誤,表示需要關閉的檔案號不存在。在使用這個函式時,需要在程式的前面包含下面的標頭檔案。

include<unistd.h>

DEMO:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
int fd_file;
char file[255]="";
strcat(strcpy(file,mainpath),"\\file.txt");
if((fd_file=open(file,O_RDONLY))==0)
{
	printf("%s\n",strerror(errno));
}
else
{
	close(fd_file);
}

檔案讀寫:

檔案讀寫指的是從檔案中讀寫資訊或將資訊寫入到檔案中。檔案讀取是使用read函式來實現的。檔案儲存是通過write函式來例項的。在進行檔案儲存的操作時,只是在檔案的緩衝區中操作,可能沒有立即寫入的到檔案中。需要使用sync或fsync函式將緩衝區中的資料寫入到檔案中。

在檔案中寫字串函式write:函式write可以把一個字串寫入到一個已經開啟的檔案中。這個函式的使用方法如下所示。

ssize_t write (int fd,void * buf,size_t count);

在引數列表中,fd是已經開啟檔案的檔案號。buf是需要寫入的字串。count是一個整型數,表示需要寫入的字元個數。size_t是一個相當於整型的資料型別,表示需要寫入的位元組的數目。將字串寫入檔案以後,檔案的讀寫位置也會隨之移動。

如果寫入成功,write函式會返回實際寫入的位元組數。發生錯誤發生時則返回-1,可以用errno來捕獲發生的錯誤。可能發生的錯誤如下所示。
EINTR:此操作被其他操作中斷。
EAGAIN: 當前開啟檔案是不可寫的方式開啟時,不能寫入檔案。
EADF:引數fd不是有效的檔案編號,或該檔案已關閉。

DEMO:

int fd_write;
char file_write[255]="";
strcat(strcpy(file_write,mainpath),"\\file_write.txt");
if((fd_write=open(file_write,O_WRONLY|O_CREAT|O_APPEND))!=0)
{
	char* write_str="I love biki!\n";
	write(fd_write,write_str,strlen(write_str));
	close(fd_write);
}

讀取檔案函式read:函式read可以從一個開啟的檔案中讀取字串。這個函式的使用方法如下所示。

ssize_t read(int fd,void *buf ,size_t count);

在引數列表中,fd表示已經開啟檔案的編號。buf是一個空指標,讀取的內容會返回到這個指標指向的字串。count表示需要讀取字元的個數。返回值表示例項讀取到的字元的個數。如果返回值為0,表示已經到達檔案末尾或檔案中沒有內容供讀取。在讀檔案時,檔案的讀寫位置會隨著讀取到的位元組移動。

當有錯誤發生時,返回值為-1,可以用errno來捕獲錯誤編號。可能返回的錯誤編號如下所示。
EINTR:此操作被其他操作中斷。
EAGAIN: 當前開啟檔案是不可寫的方式開啟時,不能寫入檔案。
EADF:引數fd不是有效的檔案編號,或該檔案已關閉。

DEMO:

int fd_file;
char file[255]="";
char file_buffer[1024];
strcat(strcpy(file,mainpath),"\\file.txt");
if((fd_file=open(file,O_RDONLY))==0)
{
	printf("%s\n",strerror(errno));
}
else
{
	read(fd_file,file_buffer,100);
	printf("%s\n",file_buffer);
	close(fd_file);
}


相關文章