a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 系統(tǒng) > Unix > 正文

UNIX高級(jí)環(huán)境編程(1)File I/O

2024-06-28 13:21:59
字體:
供稿:網(wǎng)友
UNIX高級(jí)環(huán)境編程(1)File I/O引言:

Unix系統(tǒng)中主要的文件操作包括:

  • open
  • read
  • write
  • lseek
  • close

unbuffered IO和standard I/O相對(duì)應(yīng),后面的章節(jié)我們會(huì)討論這兩者的區(qū)別。

在討論open函數(shù)的時(shí)候,會(huì)引入原子操作,多進(jìn)程通信(共享文件描述符)和內(nèi)核相關(guān)的數(shù)據(jù)結(jié)構(gòu)。

一,文件描述符

對(duì)應(yīng)內(nèi)核來說,每一個(gè)打開的文件都對(duì)應(yīng)一個(gè)非負(fù)整數(shù)。

有三個(gè)特殊的文件描述符:

  • 0表示標(biāo)準(zhǔn)輸入
  • 1表示標(biāo)準(zhǔn)輸出
  • 2表示標(biāo)準(zhǔn)錯(cuò)誤輸出

對(duì)于較新的內(nèi)核來說(linux3.2.0,Solaris10等),文件描述符的數(shù)量并沒有明確的限制,受限于內(nèi)存的大小。

二,常用的幾個(gè)文件操作函數(shù)

常用的文件操作函數(shù)包括:open,read,write,lseek,close

1 open和openat函數(shù)

函數(shù)聲明:

#include <fcntl.h>int open (const char *path, int oflag, … /* mode_t mode */);int openat (int fd, const char *path, int oflag, … /* mode_t mode */);

返回值:

OK:文件描述符(非負(fù)整數(shù))

Error:-1

注:參數(shù)列表中,“...”表示不同的系統(tǒng)和標(biāo)準(zhǔn)中,該處的參數(shù)可能不相同。

參數(shù)說明:

path:文件名

oflag:打開創(chuàng)建文件的屬性。

下面有五個(gè)必選的oflag參數(shù)值,這五個(gè)值有切只能選一個(gè)。另外還有若干個(gè)可選參數(shù)值,可以自行百度。

NewImage

細(xì)節(jié)說明:

由open和openat返回的文件描述符保證為未使用的最小的文件描述。有的應(yīng)用利用這一特性,先關(guān)閉標(biāo)準(zhǔn)輸入描述符0,就可以在標(biāo)準(zhǔn)輸入描述0上打開文件。

參數(shù)fd可以區(qū)分open和openat函數(shù)。其取值有三種可能:

  1. path表示一個(gè)絕對(duì)路徑,則fd參數(shù)無用,openat的功能和open相同;
  2. path表示一個(gè)相對(duì)路徑,則fd是一個(gè)文件描述符,指定了path在文件系統(tǒng)中的起始位置,fd為打開path父目錄時(shí)獲取的文件描述符;
  3. path表示一個(gè)相對(duì)路徑,而fd的值為AT_FDCWD,這時(shí),path的父目錄為當(dāng)前工作目錄,openat和open的功能相同。

openat函數(shù)解決了兩個(gè)問題:

  • 在多線程條件下,默認(rèn)各個(gè)線程的工作目錄時(shí)相同的(當(dāng)前工作目錄),使用這個(gè)函數(shù)可以使得各個(gè)線程的指定不同的工作目錄;
  • 提供了一種方法解決TOCTTOU(time-of-check-to-time-of-use) error。

這里介紹一下TOCTTOU錯(cuò)誤。該類錯(cuò)誤指的是,程序是非常脆弱的(vulnerable)如果該程序調(diào)用了兩個(gè)文件相關(guān)的函數(shù),第二個(gè)函數(shù)依賴于第一個(gè)函數(shù)的結(jié)果。因?yàn)閮蓚€(gè)函數(shù)是非原子操作,被操作的文件可能被兩個(gè)函數(shù)輪流操作(線程切換),導(dǎo)致第一個(gè)函數(shù)的結(jié)果出錯(cuò),從而程序出錯(cuò)。

2 creat函數(shù)

函數(shù)聲明:

#include <fcntl.h>int creat(const char* path, mode_t mode);

返回值:

  • OK:文件描述符(只寫)
  • Error:-1

creat函數(shù)相當(dāng)于下面這樣調(diào)用open函數(shù)

open (path, O_WEONLY | O_CREAT | O_TRUNC, mode);

creat有一點(diǎn)不方便,因?yàn)樗蜷_的文件描述符是只讀的,如果希望寫入之后讀回,需要依次調(diào)用creat、close和open,才能實(shí)現(xiàn)。

因此,在這種場(chǎng)景下,一個(gè)更好的打開文件的方法是像下面這樣調(diào)用open函數(shù):

open (path, O_RDWR | O_CREAT | O_TRUNC, mode);

3 close函數(shù)

函數(shù)聲明:

#include <unistd.h>int close(int fd);

返回值:

  • 0 :OK
  • -1:Error

關(guān)閉一個(gè)文件會(huì)釋放所有當(dāng)前進(jìn)程加在該文件上的記錄鎖。

4 lseek函數(shù)

每一個(gè)打開的文件都有一個(gè)”當(dāng)前文件偏移量(current file offset)“,該偏移量是一個(gè)非負(fù)整數(shù),記錄了從文件開始到當(dāng)前位置的字節(jié)數(shù)。

函數(shù)聲明:

#include <unistd.h>off_t lseek(int fd, off_t offset, int whence);

參數(shù)說明:

offset的作用取決于參數(shù)whence的值:

  • 如果whence的值是SEEK_SET,文件的偏移量設(shè)置為offset個(gè)字節(jié);
  • 如果whence的值是SEEK_CUR,文件的偏移量設(shè)置為當(dāng)前偏移量加上參數(shù)offset的值;
  • 如果whence的值是SEEK_END,文件的偏移量設(shè)置為文件長(zhǎng)度加上參數(shù)offset的值,offset可以是正值或負(fù)值。

細(xì)節(jié)說明:

獲取當(dāng)前文件偏移量的方法:

1 off_t currpos;2 3 currpos = lseek(fd, 0, SEEK_CUR);

lseek只記錄當(dāng)前文件在內(nèi)核中的偏移量,并不會(huì)引起任何的IO操作。返回的offset將會(huì)在后面的read或write函數(shù)中使用。

偏移量可以比當(dāng)前文件的長(zhǎng)度大,這時(shí),再調(diào)用write函數(shù)時(shí),將擴(kuò)展該文件的長(zhǎng)度。這樣的操作相當(dāng)于在文件中建了一個(gè)洞,該洞范圍內(nèi)讀時(shí)返回0。

使用od命令可以看到文件中的hole

NewImage

4 read函數(shù)

函數(shù)聲明:

#include <unistd.h>ssize_t read(int fd, void *buf, size_t nbytes);

返回值:

  • 正整數(shù):讀入的字節(jié)數(shù)
  • 0:文件結(jié)尾
  • -1: error

細(xì)節(jié)說明:

在一些情況下,函數(shù)返回的字節(jié)數(shù)比指定的讀入字節(jié)數(shù)要小,多數(shù)是因?yàn)樽x到了文件末尾,或者指定的讀取位置中包含的字節(jié)數(shù)小于指定的讀入字節(jié)數(shù),這時(shí),read返回的為可讀到的字節(jié)數(shù)。

5 write函數(shù)

函數(shù)聲明:

#include <unistd.h>ssize_t write (int fd, const void *buf, size_t nbytes);

返回值:

  • 非負(fù)整數(shù):寫入的字節(jié)數(shù),OK
  • -1: Error

返回值總是等于參數(shù)nbytes的值,否則就會(huì)報(bào)錯(cuò)。

對(duì)于常規(guī)的文件來說,寫操作總是從當(dāng)前文件偏移量開始。

三、小結(jié)

簡(jiǎn)單地介紹了一下常用的文件IO操作,并介紹了一些使用上的細(xì)節(jié),比較常規(guī)。

下一篇講介紹更多文件IO的特性,包括:dup,fcntl,sync,fsync和ioctl函數(shù)。。

好久沒寫博客了,又第一次用mac下的一個(gè)博客軟件寫,不太熟悉,所以寫的比較簡(jiǎn)單,以后會(huì)寫的更努力。

參考資料:

《Advanced PRogramming in the UNIX Envinronment 3rd》


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 天天色天天色 | 久久亚洲视频 | 久久久欧美| 日本在线观看视频 | 九九精品在线 | 亚洲电影一区 | 亚洲美女av在线 | 亚洲国产精品久久久久秋霞不卡 | 免费国产一区二区 | 欧美精品成人在线视频 | 九九精品免费视频 | 日韩精品一区二 | 亚欧在线观看 | 国产成人8x视频一区二区 | 一区二区三区视频免费在线观看 | 免费av手机在线观看 | 国产成人精品亚洲777人妖 | 久久久久久久国产 | 激情欧美一区 | 精品一区二区三区四区五区 | 四虎影城 | 国产精品一区二区在线看 | 欧美午夜精品久久久 | 成人高清 | 成人在线一区二区 | 亚洲视频精品 | 一区二区三区在线 | 99国内精品久久久久久久 | 欧美日韩一区二区三区在线观看 | 99久久婷婷国产精品综合 | 国产精品伦理一区二区 | 日韩精品一区二区三区在线观看 | 欧美一二区 | 国产毛片aaa | 91夜夜蜜桃臀一区二区三区 | 涩涩涩涩涩涩 | 91在线视频免费观看 | 成人av福利| 欧美日韩卡一卡二 | 一区二区三区四区视频 | 日韩欧美视频 |