<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Linux 文件操作總結

      文件是linux中的一個重要概念。在Linux中,一切(幾乎一切)都是文件。簡單的說,C中基本的的printf()函數,scanf()函數,其實都屬于文件操作。

      對于文件操作,雖然都是通過函數調用的方式實現,卻還是能分為兩類:系統調用和庫函數。

      這篇文章將先介紹linux中文件的概念,系統調用和庫函數的概念 ,然后具體的討論兩種方式下的文件操作。

      博文的主要內容如下:

      1. Linux 中的文件
      2. 文件訪問-庫函數
      3. 文件訪問-系統調用
      4. 庫函數
      5. 標準 I/O 庫
      6. /proc文件系統

      1 Linux中的文件

      1.1概念

      按照普通的定義,文件不過是一堆數據,在往下說,就是存儲器中的0101。。。而我們這里討論的文件有了更廣的定義。對于Linux中的文件,我的理解是:

      Linux中的文件具有的特點是:可通過操作系統或者程序對外提供信息,也能對內輸入信息,可以被創建,刪除。

      Linux中,文件有特別重要的意義,他們為操作系統和設備提供了一個簡單而統一的接口。在Linux中,幾乎一切都可以看做是文件 。

      這就意味著,普通程序完全可以像使用文件(普通定義)那樣使用磁盤文件、串行口、打印機和其他設備。

      硬件設備在linux操作系統中也被表示為文件。例如,可以通過如下命令把cd-rom驅動器掛載為一個文件,

      #mount -t iso9660 /dev/hdc /mnt/cdrom

      #cd /mnt/rom

      然后,就能像訪問普通文件那樣在cd-rom目錄中漫游。

      1.2操作

      和操作一般意義上的文件一樣,linux中對文件的操作只需要五個基本的函數:

      open、close、read、write和ioctl

      通過調用這幾個函數就能對linux中的文件進行讀、寫等操作。不過,這種操作又分為系統調用和庫函數調用。簡單的說,系統調用是最直接的方式,

      庫函數調用最終也是通過系統調用實現的。可認為庫函數調用是對系統調出于效率考慮而做出的優化。

      庫函數調用和系統調用的區別和聯系請參看:linux系統調用和庫函數調用的區別

      我們用很少的函數就可以對文件和設備進行訪問和控制。這些函數就是所謂的系統調用,由操作系統直接提供,他們是通向操作系統本身的接口。

      操作系統的核心部分,既內核,其實就是一組設備驅動程序。這是一些對硬件進行控制的接口。

      2 文件訪問-系統調用

      通過系統調用來訪問文件是最直接的方式。系統調用函數直接作用于操作系統內核的設備驅動程序從而實現文件訪問。

      2.1 文件描述符

      在系統中需要處理的文件(讀、寫操作)需要一個標識,以便在其它地方能識別出這個文件,于是就產生了文件描述符。文件描述符是一些小值整數,簡單的說就是

      一個文件ID用于在系統中唯一的標識文件。文件描述符的總數也就是系統可以打開文件的最多個數,這取決于系統的配置情況。

      當開始運行程序時,也就是系統開始運行時,它一般會有三個已經打開的文件描述符。他們是:

      • 0:標準輸入
      • 1:標準輸出
      • 2:標準錯誤

      其它文件的文件描述符,在調用文件打開函數open時返回。這就是說,每個設備對應著一個文件描述符。文件描述符由操作系統分配,每次分配最小的。

      2.2 write系統調用

      write,就是把緩沖區的數據寫入文件中。注意,這里的文件時廣泛意義的文件,比如寫入磁盤、寫入打印機等等。

      Linux 中write()的函數原型:

      size_t write(int fildes, const void *buf, size_t nbytes);

      參數說明:

      fildes:文件描述符,標識了要寫入的目標文件。例如:fildes的值為1,就像標準輸出寫數據,也就是在顯示屏上顯示數據;如果為 2 ,則想標注錯誤寫數據。

      *buf:待寫入的文件,是一個字符串指針。

      nbytes:要寫入的字符數。

      函數返回值:size_t  返回成功寫入文件的字符數。需要指出的是,write可能會報告說他寫入的字節比你所要求的少。這并不一定是個錯誤。在程序中,你需要檢查

      error已發現錯誤,然后再次調用write寫入剩余的數據。

      請看下面的例子:

      運行結果:

      這個程序只在標準輸出上顯示一條消息。

      read系統調用

      系統調用read是從文件中讀出數據。要讀取的文件用文件描述符標識,數據讀入一個事先定義好的緩沖區。他返回實際讀入的字節數。

      Linux中read的函數原型:

      size_t read(int fildes, void *buf, size_t nbytes);

      參數說明:

      fildes:文件描述符,標識要讀取的文件。如果為0,則從標準輸入讀數據。類似于scanf()的功能。

      *buf:緩沖區,用來存儲讀入的數據。

      nbytes:要讀取的字符數。

      返回值:size_t返回成功讀取的字符數,它可能會小于請求的字節數。

      運行結果:

      open系統調用

      系統調用open的作用是打開一個文件,并返回這個文件的描述符。

      簡單地說,open建立了一條到文件或設備的訪問路徑。如果操作成功,它將返回一個文件描述符,read和write等系統調用使用該文件描述符對文件或

      設備進行操作。這個文件描述符是唯一的,他不會和任何其他運行中的進程共享。如果兩個程序同時打開一個文件,會得到兩個不同的問價描述符。如果

      同時對兩個文件進行操作,他們各自操作,互補影響,彼此相互覆蓋(后寫入的覆蓋先寫入的)為了防止文件按讀寫沖突,可以使用文件鎖的功能。這不是

      本次重點,以后介紹。

      Linux中open的函數原型有兩個:

      int open(const char *path, int oflags);

      int open(const char *path, int oflags, mode_t mode );

      參數說明。

      path:準備打開的文件或設備名字。

      oflags:指出要打開文件的訪問模式。open調用必須指定如下所示的文件訪問模式之一:

      open調用哈可以在oflags參數中包括下列可選模式的組合(用”按位或“操作):

      • O_APPEDN: 把寫入數據追加在文件的末尾。
      • O_TRUNC: 把文件長度設為零,丟棄以后的內容。
      • O_CREAT: 如果需要,就按參數mode中給出的訪問模式創建文件。
      • O_EXCL: 與O_CREAT一起調用,確保調用者創建出文件。使用這個模式可防止兩個程序同時創建一個文件,如果文件已經存在,open調用將失敗。

       

       關于其他可能出現的oflags值,請看考open的調用手冊。

      mode:

      當使用哦、O_CREAT標志的open來創建文件時,我們必須使用三個參數格式的open調用。第三個參數mode 是幾個標志按位OR后得到的。他們是:

      • S_IRUSR: 讀權限,文件屬主。
      • S_IWUSR:寫權限,文件屬主。
      • S_ IXUSR:執行權限,文件屬主。
      • S_IRGRP:讀權限,文件所屬組。
      • S_IWGRP:寫權限,文件所屬組。

      。。。。

      請看下面例子:

      open("myfile", O_CREAT, S_IRUSR|S_IXOTH ;

      他的作用是創建一個名為myfile 的文件,文件屬主擁有讀權限,其他用戶擁有執行權限,且只有這些權限。

      運行結果:

      程序創建了一個名為myfile的文件,文件屬主有讀權限,其他用戶有執行權限,且只有這些權限。

      close系統調用

      close系統調用用于“關閉”一個文件,close調用終止一個文件描述符fildes以其文件之間的關聯。文件描述符被釋放,并能夠重新使用。

      close成功返回1,出錯返回-1.

      #Include<unistd.h>

      int close(int fildes);

      ioctl系統調用

      ioctl提供了一個用于控制設備及其描述符行為和配置底層服務的接口。終端、文件描述符、甚至磁帶機都可以又為他們定義的ioctl,具體

      細節可以參考特定設備的使用手冊。

      下面是ioctl 的函數原型

      #include<unistd.h>

      int ioctl(int fildes, int cmd,,,,,,);

      ioctl對描述符fildes指定的對象執行cmd 參數中所給出的操作。

       其他和文件管理有關的系統調用

      還有許多其他的系統調用能對文件進行操作。

      幾個常用的如:lseek()對文件描述符fildes指定文件的讀寫指針進行設置,也就是說,它可以設置文件的下一個讀寫位置。

      fstat,stat,lstat 是和文件描述符相關的函數操作,這里就不做介紹。

      dup,dup2系統調用。dup提供了復制文件描述符的方法,使我們能夠通過兩個或者更多個不同的文件描述符來訪問同一個文件。這可以用于

      在文件的不同位置對數據進行讀寫。

       

      4 庫函數

      在輸入、輸出操作中,直接使用系統調用效率會非常底。具體原因有二:

      • 系統調用會影響系統性能。與函數調用相比,系統調用的開銷大。因為在執行系統調用的時候,要切換到內核代碼區執行,然后再返回用戶代碼。這必然就需要大量的時間開支。一種解決辦法是:盡量減少系統調用的次數,讓每次系統調用完成盡可能多的 任務。例如每次系統調用寫入大量的字符而不是單個字符。
      • 硬件會對系統調用一次能讀寫的數據塊做一定的限制。例如,磁帶機通常的寫操作數據塊長度是10k,如果縮寫數據不是10k的整數倍,磁帶機還是會以10k為單位繞磁帶,這就在磁帶上留下空隙。

      為了提高文件訪問操作的效率,并且使得文件操作變得更方便,Linux發行版提供了一系列的標準函數庫。他們是一些由函數構成的集合,你可以在自己的程序方便的中使用它們,

      去操作文件。提供輸出緩沖功能的標準I/O庫就是這樣的例子。你可以高效的寫任意長度的數據塊,庫函數則在需要的時候安排底層函數調用(系統調用)

      也就是說,庫函數在用戶和系統之間,增加了一個中間層。如下圖所示:

      庫函數是根據實際需要而包裝好的系統調用,用戶可在程序中方便的使用庫函數,如標準I O庫(稍后會講)

       

      5 標準I/O庫

       標準I/O庫及其頭文件<stdio.h>為底層I/O系統調用提供了一個通用的接口。這個庫現在已經成為ANSI標準C的一部分,而前面所講的系統調用卻不是。

      標準I/O庫提供了許多復雜功能的函數,用于格式化輸出和掃描輸入,它還負責滿足設備的緩沖需求。

      在許多方面,使用標準I/O庫和使用底層文件描述符類似。需要先打開一個文件,已建立一個文件訪問路徑(也就是系統調用中的文件描述符)

      在標準I/O庫中,與文件描述符對應的叫 流(stream),它被實現為指向結構FILE的指針。

      在啟動程序時,有三個文件流是自動打開的。他們是:

      • stdin: 標準輸入
      • stdout: 標準輸出
      • stderr: 標準錯誤輸出

      下面會介紹一些常用的I/O庫函數:

      5.1 fopen函數

      fopen函數類似于系統調用中的open函數。和open一樣,它返回文件的標識符,只是這里叫做流(stream),在庫函數里實現為一個指向文件的指針。

      如果需要對設備的行為進行明確的控制,最好使用底層系統調用,因為這可以避免使用庫函數帶來的一些非預期的副作用,如輸入/輸出緩沖。

      函數原型:

      #include<stdio.h>

      FILE *fopen(const char *filename, const char *mode);

      參數說明:

      *filename:打開文件的文件名

      *mode:打開的方式

           r 以只讀方式打開文件,該文件必須存在。
        r+ 以可讀寫方式打開文件,該文件必須存在。
        rb+ 讀寫打開一個二進制文件,允許讀數據。
        rw+ 讀寫打開一個文本文件,允許讀和寫。
        w 打開只寫文件,若文件存在則文件長度清為0,即該文件內容會消失。若文件不存在則建立該文件
        w+ 打開可讀寫文件,若文件存在則文件長度清為零,即該文件內容會消失。若文件不存在則建立該文件。

      fopen在成功是返回一個非空的FILE *指針。失敗返回NULL

      5.2 fread/fwrite函數

      fread函數從文件流中讀取數據,對應于系統調用中的read;fwrite函數從文件流中寫數據,對應于系統調用中的write

      函數原型:

      #include<stdio.h>

      size_t  fread(void *ptr, size_t size, size_t nitems, FILE *stream);

      參數說明:

      *ptr 要讀取數據的緩沖區,也就是要存放讀取數據的地方。

      size:指定每個數據記錄的長度。

      nitems: 計數,給出要傳輸的記錄個數。

      返回值:成功讀取到數據緩沖區的記錄個數,當到達文件尾時,他的返回值可能會消耗與nitems,甚至可以是0

      size_t  fwrite(const coid *ptr, size_t size , size_t nitimes, FILE *stream);

      他從指定的數據緩沖區ptr中把數據寫入文件流,返回成功寫入的記錄個數。

      5.3 fclose函數

      fclose函數關閉指定的文件流stream,這個操作會使所有未寫出的數據都寫出。因為stdio庫函數會對數據進行緩沖,所有調用fclose函數是很重要的。

      如果程序需要確保數據已經全部寫出,就應該調用fclose函數。雖然程序正常結束時,也會自動的調用fclose函數,但這樣就不能檢測出調用fclose所產生的錯誤了。

      函數原型如下:

      #include<stdio,h>

      int fclose(FILE *stream);

      5.4 fflush函數

      fflush函數的作用是把文件流中所有未寫出的數據全部寫出。 處于效率考慮,在使用庫函數的時候會使用數據緩沖區,當緩沖區滿的時候才進行寫操作。使用fflush函數

      可以將緩沖區的數據全部寫出,而不關心緩沖區是否滿。fclose的執行隱含調用了fflush函數,所以不必再fclose執行之前調用fflush。

      函數原型:

      #include<stdio.h>

      int fflush(FILE *stream);

       

       

       

      6 /proc文件系統

       Linux將一切看做文件,硬件設備在文件系統中也有相應的條目。/dev目錄中的文件使用底層系統調用這樣一種特殊方式來訪問硬件。

      /proc文件系統,可以看做是一個特殊的文件系統,在這個系統中,每個文件都對應一個獨立的硬件,所以用戶可以通過proc文件系統像訪問文件一樣來訪問硬件設備。

      該文件系統通常表現為/proc 目錄。該目錄中包含了許多特殊文件以允許對驅動和內核信息進行高層訪問。

      如果你想知道CPU的信息,內核版本信息等,就可以通過proc文件系統。

      /proc目錄中的文件會隨系統的不同而不同。我的電腦上的/proc 中的文件如下所示:

       在多數情況下,直接讀取這些文件就可以獲得狀態信息。

      6.1 訪問設備信息

      例如,獲取CPU的信息:

      內存使用信息(只顯示里局部~):

      每次讀這些文件的內容時,他們所提供的信息都會及時更新。所以再讀一次meminfo文件會得到不同的結果。

      由特定內核函數給出的更多信息可以在proc目錄的子目錄中查到。

      6.2 查看內核函數給出的信息

      例如:查看網絡套接字的使用統計:

      6.3通過proc查看進程信息

      用ps 命令可得到當前正在運行的進程,每個進程在proc中都有相應的信息文件,通過查看這個文件,可以得知進程相關的信息:

      進程2754的當前工作目錄是:/hme/yyl

      程序 /bin/su正在運行,還有其他信息此處不再說明;

      修改proc文件系統內容

      例如,系統中所有運行的程序同時打開的文件總數是Linux內核的一個參數。

      如果我們想要增大這個歌值,則可通過寫同一個文件來實現。

      注意:對proc的寫操作要注意權限問題,在修改時要小心,不適當的值可能會影響到系統的一運行。

       

       

       

       

      參看資料:Linux 程序設計

      如有轉載請注明出處:http://www.rzrgm.cn/yanlingyin/

      geek_ling、尹雁鈴@ 博客園 2012-8-04

       E-mail:yanlingyin@yeah.net

       

      posted @ 2012-08-04 09:38  Geek_Ling  閱讀(68549)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 曰韩高清砖码一二区视频| 国产一区二区不卡自拍| 一区二区三区黄色一级片| 护士张开腿被奷日出白浆| 国产系列丝袜熟女精品视频 | 人妻激情偷乱一区二区三区| 国产亚洲精品久久久久久久软件| 天堂资源在线| 国产高清免费午夜在线视频| 山西省| 免费无码午夜理论电影| 国产性生大片免费观看性| 九九re线精品视频在线观看视频| 日韩乱码人妻无码中文字幕视频| 国产边打电话边被躁视频| 日韩一区二区三区精彩视频| 婷婷综合久久狠狠色成人网| 长武县| 亚洲国产片一区二区三区| 国产视频深夜在线观看| 国产精品白丝久久AV网站| 欧美videos粗暴| 亚洲性图日本一区二区三区| 国产成AV人片久青草影院| 陆丰市| 精品国产一区av天美传媒| 久99久热这里只有精品| 深夜av在线免费观看| 国产精品99久久久久久董美香| 欧美大胆老熟妇乱子伦视频| 偷自拍另类亚洲清纯唯美| 玩弄放荡人妻少妇系列| AV秘 无码一区二| 午夜爽爽爽男女免费观看影院 | 久热这里有精品视频播放| 久热99热这里只有精品| 18禁美女裸体爆乳无遮挡| 亚洲偷自拍国综合| av无码小缝喷白浆在线观看| 久久经精品久久精品免费观看| 性按摩玩人妻hd中文字幕|