C語言-系統(tǒng)-文件操作

1. Linux 文件

Linux 常見的文件類型:普通文件载慈、目錄文件惭等、設(shè)備文件、管道文件办铡、套接字和鏈接文件等等辞做。它們的分別用 -、d寡具、c秤茅、p、s和 l 表示童叠。


圖片1
  1. 普通文件
    普通文件是指普通計算機(jī)用戶看到的文件框喳,它們常駐留在磁盤的某處。通常分為文本文件和二進(jìn)制文件厦坛。
    文本文件:以文本的某種編碼形式存儲在存儲器中五垮,它是以“行”為基本結(jié)構(gòu)的一種信息組織和存儲方式。
    二進(jìn)制文件:以文本的二進(jìn)制形式存儲才在計算機(jī)中粪般,用戶一般不能直接讀懂它們拼余,只能通過相應(yīng)的軟件才能將其顯示出來。二進(jìn)制文件一般是可執(zhí)行程序亩歹、圖形匙监、圖像、聲音等等小作。
  2. 目錄文件
    目錄文件:主要目的是用于管理和組織系統(tǒng)中的大量文件亭姥。它存儲一組相關(guān)文件的位置、大小等與文件相關(guān)的信息顾稀。
  3. 設(shè)備文件
    設(shè)備文件:Linux系統(tǒng)把每一個I/O設(shè)備都看成一個文件达罗,與普通文件一樣處理;可以細(xì)分為塊設(shè)備文件(表示文件系統(tǒng)高速緩存的設(shè)備,例如硬盤驅(qū)動器)和字符設(shè)備文件(表示非高速緩存的設(shè)備粮揉,例如鼠標(biāo)巡李、系統(tǒng)終端)。前者的存取是以一個個字符塊為單位的扶认,后者則是以單個字符為單位的侨拦。
  4. 管道文件
    管道文件:主要用于在進(jìn)程間傳遞數(shù)據(jù)。管道文件又稱先進(jìn)先出(FIFO)文件辐宾。管道文件只針對兩個進(jìn)程間的通信而設(shè)計狱从,建立管道的時候,實(shí)際獲得兩個文件描述符:一個用于讀取而另一個用于寫入叠纹。任何寫入管道寫入端的數(shù)據(jù)都可以從讀取端讀出季研。
  5. 套接字文件
    套接字文件:類似于管道文件。管道文件用于本地通信誉察,而套接字允許網(wǎng)絡(luò)上的通信与涡。
  6. 鏈接文件
    鏈接文件:這個文件包含了另一個文件的路徑名。被連接的文件可以是任意文件和目錄持偏,可以連接不同文件系統(tǒng)的文件递沪,鏈接文件甚至可以連接不存在的文件,這就產(chǎn)生“斷鏈”的問題综液,鏈接文件甚至可以循環(huán)鏈接自己。

2. 文件的操作

Linux 最常用的文件操作系統(tǒng)調(diào)用包括:創(chuàng)建儒飒、打開文件 open()和create()谬莹,關(guān)閉文件close(),讀取文件read()桩了,寫入文件write()附帽,移動文件指針lseek(),文件控制fcntl()和access()井誉。

1. 創(chuàng)建打開文件

open():
頭文件:#include<sys/types.h>/<sys/stat.h>/<fcntl.h>
函數(shù)的一般形式:

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

參數(shù)設(shè)置:

  1. pathname:是文件路徑
  2. flags:文件打開的方式
O_RDONLY 以只讀方式打開文件
O_WRONLY 以只寫方式打開文件
O_RDWR 以可讀寫方式打開文件. 上述三種旗標(biāo)是互斥的, 也就是不可同時使用, 但可與下列的旗標(biāo)利用OR(|)運(yùn)算符組合.
O_CREAT 若欲打開的文件不存在則自動建立該文件.
O_EXCL 如果O_CREAT 也被設(shè)置, 此指令會去檢查文件是否存在. 文件若不存在則建立該文件, 否則將導(dǎo)致打開文件錯誤. 此外, 若O_CREAT 與O_EXCL 同時設(shè)置, 并且欲打開的文件為符號連接, 則會打開文件失敗.
O_NOCTTY 如果欲打開的文件為終端機(jī)設(shè)備時, 則不會將該終端機(jī)當(dāng)成進(jìn)程控制終端機(jī).
O_TRUNC 若文件存在并且以可寫的方式打開時, 此旗標(biāo)會令文件長度清為0, 而原來存于該文件的資料也會消失.
O_APPEND 當(dāng)讀寫文件時會從文件尾開始移動, 也就是所寫入的數(shù)據(jù)會以附加的方式加入到文件后面.
O_NONBLOCK 以不可阻斷的方式打開文件, 也就是無論有無數(shù)據(jù)讀取或等待, 都會立即返回進(jìn)程之中.
O_NDELAY 同O_NONBLOCK.
O_SYNC 以同步的方式打開文件.
O_NOFOLLOW 如果參數(shù)pathname 所指的文件為一符號連接, 則會令打開文件失敗.
O_DIRECTORY 如果參數(shù)pathname 所指的文件并非為一目錄, 則會令打開文件失敗 //注:此為Linux2. 2 以后特有的旗標(biāo), 以避免一些系統(tǒng)安全問題. 
  1. mode: 則有下列數(shù)種組合, 只有在建立新文件時才會生效, 此外真正建文件時的權(quán)限會受到umask 值所影響, 因此該文件權(quán)限應(yīng)該為 (mode-umaks)蕉扮。
S_IRWXU00700 權(quán)限, 代表該文件所有者具有可讀、可寫及可執(zhí)行的權(quán)限.
S_IRUSR 或S_IREAD, 00400 權(quán)限, 代表該文件所有者具有可讀取的權(quán)限.
S_IWUSR 或S_IWRITE, 00200 權(quán)限, 代表該文件所有者具有可寫入的權(quán)限.
S_IXUSR 或S_IEXEC, 00100 權(quán)限, 代表該文件所有者具有可執(zhí)行的權(quán)限.
S_IRWXG 00070 權(quán)限, 代表該文件用戶組具有可讀颗圣、可寫及可執(zhí)行的權(quán)限.
S_IRGRP 00040 權(quán)限, 代表該文件用戶組具有可讀的權(quán)限.
S_IWGRP 00020 權(quán)限, 代表該文件用戶組具有可寫入的權(quán)限.
S_IXGRP 00010 權(quán)限, 代表該文件用戶組具有可執(zhí)行的權(quán)限.
S_IRWXO 00007 權(quán)限, 代表其他用戶具有可讀喳钟、可寫及可執(zhí)行的權(quán)限.
S_IROTH 00004 權(quán)限, 代表其他用戶具有可讀的權(quán)限
S_IWOTH 00002 權(quán)限, 代表其他用戶具有可寫入的權(quán)限.
S_IXOTH 00001 權(quán)限, 代表其他用戶具有可執(zhí)行的權(quán)限.

返回值:成功返回文件描述符,失敗返回 -1在岂。
錯誤代碼:

EEXIST 參數(shù)pathname 所指的文件已存在, 卻使用了O_CREAT 和O_EXCL 旗標(biāo).
EACCESS 參數(shù)pathname 所指的文件不符合所要求測試的權(quán)限.
EROFS 欲測試寫入權(quán)限的文件存在于只讀文件系統(tǒng)內(nèi).
EFAULT 參數(shù)pathname 指針超出可存取內(nèi)存空間.
EINVAL 參數(shù)mode 不正確.
ENAMETOOLONG 參數(shù) pathname 太長.
ENOTDIR 參數(shù)pathname 不是目錄.
ENOMEM 核心內(nèi)存不足.
ELOOP 參數(shù)pathname 有過多符號連接問題.
EIO I/O 存取錯誤.

2. 關(guān)閉文件

close():
頭文件:#include<unsitd.h>
函數(shù)的一般形式:int close(int fd);
參數(shù)設(shè)置:

fd:想要關(guān)閉的文件的文件描述奔则。

返回值:成功返回0,失敗返回 -1蔽午。
錯誤代碼:EBADF 參數(shù)fd 非有效的文件描述詞或該文件已關(guān)閉易茬。

3. 讀取文件

read():
頭文件:#include<unsitd.h>
函數(shù)的一般形式:ssize_t read(int fd, void * buf, size_t count);
參數(shù)設(shè)置:

fd:要讀取的文件的文件描述;
buf:讀取的字符放在buf指針?biāo)傅膬?nèi)存中及老;
count:要讀取的字符數(shù)抽莱。

返回值:成功返回讀取的實(shí)際字節(jié)數(shù)范抓,失敗返回 -1。
錯誤代碼:

EINTR 此調(diào)用被信號所中斷.
EAGAIN 當(dāng)使用不可阻斷I/O 時(O_NONBLOCK), 若無數(shù)據(jù)可讀取則返回此值.
EBADF 參數(shù)fd 非有效的文件描述詞, 或該文件已關(guān)閉.

4. 寫入文件

write():
頭文件:#include<unsitd.h>
函數(shù)的一般形式:ssize_t write (int fd, const void * buf, size_t count);
參數(shù)設(shè)置:

fd:要寫入文件的文件描述食铐;
buf:寫入的字符放在buf指針?biāo)傅膬?nèi)存中匕垫;
count:要寫入的字符數(shù)。

返回值:成功返回寫入的實(shí)際字節(jié)數(shù)璃岳,失敗返回 -1年缎。
錯誤代碼:

EINTR 此調(diào)用被信號所中斷.
EAGAIN 當(dāng)使用不可阻斷I/O 時 (O_NONBLOCK), 若無數(shù)據(jù)可讀取則返回此值.
EADF 參數(shù)fd 非有效的文件描述詞, 或該文件已關(guān)閉.

5. 文件隨機(jī)存取

lseek():
頭文件:#include <sys/types.h> #include <unistd.h>
函數(shù)的一般形式:off_t lseek(int fildes, off_t offset, int whence);
參數(shù)設(shè)置:

fildes:已打開的文件描述符
offset:根據(jù)參數(shù)whence來移動讀寫位置的位移數(shù)。
whence:文件內(nèi)容指針的位置

    SEEK_SET 參數(shù)offset 即為新的讀寫位置.
    SEEK_CUR 以目前的讀寫位置往后增加offset 個位移量.
    SEEK_END 將讀寫位置指向文件尾后再增加offset 個位移量. 當(dāng)whence 值為SEEK_CUR 或SEEK_END 時, 參數(shù)offet 允許負(fù)值的出現(xiàn).

返回值:當(dāng)調(diào)用成功時則返回目前的讀寫位置, 也就是距離文件開頭多少個字節(jié). 若有錯誤則返回-1铃慷。

// 常用的使用方法:
1) 欲將讀寫位置移到文件開頭時:lseek(int fildes, 0, SEEK_SET);
2) 欲將讀寫位置移到文件尾時:lseek(int fildes, 0, SEEK_END);
3) 想要取得目前文件位置時:lseek(int fildes, 0, SEEK_CUR);

3. 案例

#include <stdio.h>
#include <stdlib.h>  //exit
#include <string.h> //memset
#include <unistd.h>  // read(),write(),close()
// open()
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
  int fd = -1单芜, num = -1;
  char buf[10];
  fd = open("./myfile.text", O_RDWD | O_CREAT); //打開文件,若沒有文件犁柜,則在當(dāng)前目錄下創(chuàng)建該文件
  if (-1 == fd)
  {
    perror("open:");
    exit(1);
  }
  printf("input buf[10]:");
  scanf("%s", buf);
  write(fd, buf, sizeof(buf));  //寫入文件當(dāng)中
  memset(buf, '\0', 10); //清空buf[10]
  printf("after clear buf:%s\n", buf);
  lseek(fd, 0, SEEK_SET); //文件指針跳轉(zhuǎn)到文件頭
  num = read(fd, buf, sizeof(buf)); //讀取文件中的內(nèi)容
  if (-1 == num)
  {
    perror("read:");
    exit(1);
  }
  printf("read ./myfile.text message num :%d\n", num);
  close(fd);  //關(guān)閉文件描述符
  return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末洲鸠,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子馋缅,更是在濱河造成了極大的恐慌扒腕,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件萤悴,死亡現(xiàn)場離奇詭異瘾腰,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)覆履,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門蹋盆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人硝全,你說我怎么就攤上這事栖雾。” “怎么了伟众?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵析藕,是天一觀的道長。 經(jīng)常有香客問我凳厢,道長账胧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任先紫,我火速辦了婚禮找爱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘泡孩。我一直安慰自己车摄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吮播,像睡著了一般变屁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上意狠,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天粟关,我揣著相機(jī)與錄音,去河邊找鬼环戈。 笑死闷板,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的院塞。 我是一名探鬼主播遮晚,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼拦止!你這毒婦竟也來了县遣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤汹族,失蹤者是張志新(化名)和其女友劉穎萧求,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體顶瞒,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡夸政,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了榴徐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秒梳。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖箕速,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情朋譬,我是刑警寧澤盐茎,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站徙赢,受9級特大地震影響字柠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜狡赐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一窑业、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧枕屉,春花似錦常柄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卷玉。三九已至,卻和暖如春喷市,著一層夾襖步出監(jiān)牢的瞬間相种,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工品姓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寝并,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓腹备,卻偏偏與公主長得像衬潦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子馏谨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容