- Linux程序設(shè)計(jì)(第4版)
- (英)Neil Matthew Richard Stones
- 2407字
- 2021-04-09 20:04:43
3.1 Linux文件結(jié)構(gòu)
你可能會(huì)問(wèn);“為什么要在這里討論文件結(jié)構(gòu)呢?我早知道它了。”這么說(shuō)吧,與UNIX一樣,Linux環(huán)境中的文件具有特別重要的意義,因?yàn)樗鼈優(yōu)椴僮飨到y(tǒng)服務(wù)和設(shè)備提供了一個(gè)簡(jiǎn)單而一致的接口。在Linux中,一切(或幾乎一切)都是文件。
這就意味著,通常程序完全可以像使用文件那樣使用磁盤(pán)文件、串行口、打印機(jī)和其他設(shè)備。在本書(shū)后面的內(nèi)容中,我們將介紹一些例外情況,比如第15章中的網(wǎng)絡(luò)連接。但大多數(shù)情況下,你只需要使用5個(gè)基本的函數(shù)——open、close、read、write和ioctl。
目錄也是文件,但它是一種特殊類(lèi)型的文件。在現(xiàn)代的UNIX(包括Linux)版本中,即使是超級(jí)用戶可能也不再被允許直接對(duì)目錄進(jìn)行寫(xiě)操作了。所有用戶通常都使用上層的opendir/readdir接口來(lái)讀取目錄,而無(wú)需了解特定系統(tǒng)中目錄實(shí)現(xiàn)的具體細(xì)節(jié)。我們將在本章的后面介紹專(zhuān)門(mén)的目錄函數(shù)。
可以這么說(shuō),Linux中的任何事物都可以用一個(gè)文件來(lái)表示,或者通過(guò)特殊的文件提供。雖然它們會(huì)與你熟悉的傳統(tǒng)文件有一些細(xì)微的區(qū)別,但兩者的基本原理是一致的。下面就讓我們來(lái)看看到目前為止我們提到的一些特殊文件。
3.1.1 目錄
文件,除了本身包含的內(nèi)容以外,它還會(huì)有一個(gè)名字和一些屬性,即“管理信息”,包括文件的創(chuàng)建/修改日期和它的訪問(wèn)權(quán)限。這些屬性被保存在文件的inode(節(jié)點(diǎn))中,它是文件系統(tǒng)中的一個(gè)特殊的數(shù)據(jù)塊,它同時(shí)還包含文件的長(zhǎng)度和文件在磁盤(pán)上的存放位置。系統(tǒng)使用的是文件的inode編號(hào),目錄結(jié)構(gòu)為文件命名僅僅是為了便于人們使用。
目錄是用于保存其他文件的節(jié)點(diǎn)號(hào)和名字的文件。目錄文件中的每個(gè)數(shù)據(jù)項(xiàng)都是指向某個(gè)文件節(jié)點(diǎn)的鏈接,刪除文件名就等于刪除與之對(duì)應(yīng)的鏈接(文件的節(jié)點(diǎn)號(hào)可以通過(guò)ls -i命令查看)。你可以通過(guò)使用ln命令在不同的目錄中創(chuàng)建指向同一個(gè)文件的鏈接。
刪除一個(gè)文件時(shí),實(shí)質(zhì)上是刪除了該文件對(duì)應(yīng)的目錄項(xiàng),同時(shí)指向該文件的鏈接數(shù)減1。該文件中的數(shù)據(jù)可能仍然能夠通過(guò)其他指向同一文件的鏈接訪問(wèn)到。如果指向某個(gè)文件的鏈接數(shù)(即ls -l命令的輸出中跟在訪問(wèn)權(quán)限后面的那個(gè)數(shù)字)變?yōu)榱悖捅硎驹摴?jié)點(diǎn)以及其指向的數(shù)據(jù)不再被使用,磁盤(pán)上的相應(yīng)位置就會(huì)被標(biāo)記為可用空間。
文件被安排在目錄中,目錄中可能還包含子目錄。這些構(gòu)成了我們所熟悉的文件系統(tǒng)層次結(jié)構(gòu)。用戶(比如neil)通常會(huì)將自己的文件保存在家目錄中,這可能是目錄/home/neil,該目錄還將包含用于保存電子郵件、商業(yè)信函、工具程序等的子目錄。注意,許多UNIX和Linux的shell都允許用戶通過(guò)波浪線符號(hào)(~)直接進(jìn)入自己的家目錄。要想進(jìn)入他人的家目錄,就鍵入~user(~加用戶名)即可。如你所知,每個(gè)用戶的家目錄通常是一個(gè)上層目錄的子目錄,這個(gè)上層目錄是專(zhuān)為此目的而創(chuàng)建的,在本例中,它就是/home目錄。
注意,糟糕的是,標(biāo)準(zhǔn)庫(kù)函數(shù)不能理解文件名參數(shù)中的shell波浪線速記符號(hào),所以你必須始終在自己的程序中使用真實(shí)的文件名。
/home目錄本身又是根目錄/的一個(gè)子目錄,根目錄位于目錄層次的最頂端,它在它的各級(jí)子目錄中包含著系統(tǒng)中的所有文件。根目錄中通常包含用于存放系統(tǒng)程序(二進(jìn)制可執(zhí)行文件)的/bin子目錄、用于存放系統(tǒng)配置文件的/etc子目錄和用于存放系統(tǒng)函數(shù)庫(kù)的/lib子目錄。代表物理設(shè)備并為這些設(shè)備提供接口的文件按照慣例會(huì)被放在/dev子目錄中。圖3-1顯示了一個(gè)典型的Linux目錄結(jié)構(gòu)的一部分。關(guān)于Linux文件系統(tǒng)布局的更多信息請(qǐng)見(jiàn)第18章中有關(guān)Linux文件系統(tǒng)標(biāo)準(zhǔn)的討論。

圖3-1
3.1.2 文件和設(shè)備
甚至硬件設(shè)備在Linux中通常也被表示(映射)為文件。例如,作為超級(jí)用戶,你可以使用如下命令將IDE CD-ROM驅(qū)動(dòng)器掛載為一個(gè)文件:

這個(gè)命令將CD-ROM設(shè)備(在本例中,是在系統(tǒng)啟動(dòng)時(shí)被裝載為/dev/hdc的第二個(gè)主IDE設(shè)備,其他類(lèi)型的設(shè)備對(duì)應(yīng)不同的/dev條目)中的當(dāng)前內(nèi)容掛載為/mnt/cdrom目錄下的文件結(jié)構(gòu)。然后,你就可以像往常一樣瀏覽CD-ROM的目錄,只不過(guò)該目錄中的內(nèi)容是只讀的。
UNIX和Linux中比較重要的設(shè)備文件有3個(gè):/dev/console、/dev/tty和/dev/null。
1./dev/console
這個(gè)設(shè)備代表的是系統(tǒng)控制臺(tái)。錯(cuò)誤信息和診斷信息通常會(huì)被發(fā)送到這個(gè)設(shè)備。每個(gè)UNIX系統(tǒng)都會(huì)有一個(gè)指定的終端或顯示屏用來(lái)接收控制臺(tái)消息。過(guò)去,它可能是一臺(tái)專(zhuān)用的打印終端。在現(xiàn)代的工作站和Linux上,它通常是“活躍”的虛擬控制臺(tái);而在X視窗系統(tǒng)中,它會(huì)是屏幕上一個(gè)特殊的控制臺(tái)窗口。
2./dev/tty
如果一個(gè)進(jìn)程有控制終端的話,那么特殊文件/dev/tty就是這個(gè)控制終端(鍵盤(pán)和顯示屏,或鍵盤(pán)和窗口)的別名(邏輯設(shè)備)。例如,由系統(tǒng)自動(dòng)運(yùn)行的進(jìn)程和腳本就沒(méi)有控制終端,所以它們不能打開(kāi)/dev/tty。
在能夠使用該設(shè)備文件的情況下,/dev/tty允許程序直接向用戶輸出信息,而不管用戶具體使用的是哪種類(lèi)型的偽終端或硬件終端。在標(biāo)準(zhǔn)輸出被重定向時(shí),這一功能非常有用。使用命令ls -R |more顯示一個(gè)長(zhǎng)目錄列表就是一個(gè)這樣的例子,more程序需要提示用戶進(jìn)行鍵盤(pán)操作之后才能顯示下一頁(yè)內(nèi)容。你將在第5章中看到更多使用/dev/tty的例子。
注意,雖然/dev/console設(shè)備只有一個(gè),但通過(guò)/dev/tty卻能夠訪問(wèn)許多不同的物理設(shè)備。
3./dev/null
/dev/null文件是空(null)設(shè)備。所有寫(xiě)向這個(gè)設(shè)備的輸出都將被丟棄,而讀這個(gè)設(shè)備會(huì)立刻返回一個(gè)文件尾標(biāo)志,所以在cp命令里可以把它用做復(fù)制空文件的源文件。人們常把不需要的輸出重定向到/dev/null。
創(chuàng)建空文件的另一個(gè)方法是使用touch <filename>命令,該命令的作用是改變文件的修改時(shí)間。如果指定的文件不存在,就創(chuàng)建它,但該命令并不會(huì)把有內(nèi)容的文件變成空文件。

/dev目錄中的其他設(shè)備包括:硬盤(pán)和軟盤(pán)、通信端口、磁帶驅(qū)動(dòng)器、CD-ROM、聲卡以及一些代表系統(tǒng)內(nèi)部工作狀態(tài)的設(shè)備。該目錄中甚至還有/dev/zero設(shè)備,它可以作為創(chuàng)建空文件的null字節(jié)源。訪問(wèn)該目錄中的某些設(shè)備需要具有超級(jí)用戶權(quán)限,普通用戶不能通過(guò)編寫(xiě)程序來(lái)直接訪問(wèn)如硬盤(pán)這樣的底層設(shè)備。設(shè)備文件的名字會(huì)隨系統(tǒng)的不同而不同。Linux發(fā)行版通常都提供了以超級(jí)用戶身份運(yùn)行的應(yīng)用程序,用來(lái)管理那些以其他用戶身份無(wú)法訪問(wèn)的設(shè)備,例如,用于掛載文件系統(tǒng)的mount命令。
設(shè)備被分為字符設(shè)備和塊設(shè)備。兩者區(qū)別在于訪問(wèn)設(shè)備時(shí)是否需要一次讀寫(xiě)一整塊。一般情況下,塊設(shè)備是那些支持某些類(lèi)型文件系統(tǒng)的設(shè)備,例如硬盤(pán)。
在本章中,我們將集中討論磁盤(pán)文件和目錄。我們將在第5章中討論另一種設(shè)備——用戶終端。
- HornetQ Messaging Developer’s Guide
- Spring Boot開(kāi)發(fā)與測(cè)試實(shí)戰(zhàn)
- Drupal 8 Blueprints
- Mastering OpenCV Android Application Programming
- Python Deep Learning
- 數(shù)據(jù)結(jié)構(gòu)與算法JavaScript描述
- JS全書(shū):JavaScript Web前端開(kāi)發(fā)指南
- Learning FuelPHP for Effective PHP Development
- iOS開(kāi)發(fā)實(shí)戰(zhàn):從入門(mén)到上架App Store(第2版) (移動(dòng)開(kāi)發(fā)叢書(shū))
- 汽車(chē)人機(jī)交互界面整合設(shè)計(jì)
- C語(yǔ)言程序設(shè)計(jì)
- Instant Automapper
- C語(yǔ)言程序設(shè)計(jì)實(shí)驗(yàn)指導(dǎo)與習(xí)題精解
- LabVIEW數(shù)據(jù)采集(第2版)
- JSP編程教程