Linux(C/C++)下的檔案操作open、fopen與freopen

來源:互聯網
上載者:User

標籤:變數   val   作用   記憶體   原型   --   建立檔案   常量   資料   

Linux(C/C++)下的檔案操作open、fopen與freopen


open是linux下的底層系統調用函數,fopen與freopen c/c++下的標準I/O庫函數,帶輸入/輸出緩衝。
linxu下的fopen是open的封裝函數,fopen終於還是要調用底層的系統調用open。
所以在linux下假設須要對裝置進行明白的控制。那最好使用底層系統調用(open),


open相應的檔案操作有:close, read, write,ioctl 等。
fopen 相應的檔案操作有:fclose, fread, fwrite, freopen, fseek, ftell, rewind等。
freopen用於重新導向輸入輸出資料流的函數,該函數能夠在不改變代碼原貌的情況下改變輸入輸出環境。但使用時應當保證流是可靠的。具體見第3部分。

-------------------------------------------------------------------------------------------------------------------
open和fopen的差別:
1,fread是帶緩衝的,read不帶緩衝.  
2,fopen是標準c裡定義的,open是POSIX中定義的.  
3,fread能夠讀一個結構.read在linux/unix中讀二進位與普通檔案沒有差別.  
4,fopen不能指定要建立檔案的許可權.open能夠指定許可權.  
5,fopen返迴文件指標,open返迴文件描寫敘述符(整數).  
6,linux/unix中不論什麼裝置都是檔案,都能夠用open,read.

-------------------------------------------------------------------------------------------------------------------

1、open系統調用(linux)
須要包括標頭檔:#include<sys/types.h>
                            #include<sys/stat.h>
                            #include<fcntl.h> 

函數原型:int open( const char * pathname, int oflags);
                  int open( const char * pathname,int oflags, mode_t mode);
          
mode僅當建立新檔案時才使用。用於指定檔案的訪問許可權。

pathname 是待開啟/建立檔案的路徑名。

oflags用於指定檔案的開啟/建立模式,這個參數可由下面常量(定義於 fcntl.h)通過邏輯或構成。
   O_RDONLY       僅僅讀模式 
   O_WRONLY      僅僅寫入模式 
   O_RDWR          讀寫入模式
以上三者是相互排斥的,即不能夠同一時候使用。

開啟/建立檔案時。至少得使用上述三個常量中的一個。

下面常量是選用的:
   O_APPEND         每次寫操作都寫入檔案的末尾 
   O_CREAT            假設指定檔案不存在,則建立這個檔案 
   O_EXCL               假設要建立的檔案已存在,則返回 -1,而且改動 errno 的值
   O_TRUNC           假設檔案存在,而且以僅僅寫/讀寫方式開啟,則清空檔案所有內容 
   O_NOCTTY         假設路徑名指向終端裝置,不要把這個裝置用作控制終端。
   O_NONBLOCK   假設路徑名指向 FIFO/塊檔案/字元檔案,則把檔案的開啟和後繼 I/O設定為非堵塞模式(nonblocking mode)。


//下面用於同步輸入輸出
   O_DSYNC          等待物理 I/O 結束後再 write。在不影響讀取新寫入的資料的前提下,不等待檔案屬性更新。 
   O_RSYNC          read 等待全部寫入同一地區的寫操作完畢後再進行
   O_SYNC            等待物理 I/O 結束後再 write,包含更新檔案屬性的 I/O


當你使用帶有O_CREAT標誌的open調用來建立檔案時,你必須使用有3個參數格式的open調用。

第三個參數mode是幾個標誌按位或後得到的,
這些標誌在標頭檔sys/stat.h中定義。例如以下所看到的:
  S_IRUSR:    讀許可權,檔案屬主
  S_IWUSR:   寫入權限,檔案屬主
  S_IXUSR:    運行許可權,檔案屬主
  S_IRGRP:    讀許可權,檔案所屬組
  S_IWGRP:   寫入權限,檔案所屬組
  S_IXGRP:    運行許可權。檔案所屬組
  S_IROTH:   讀許可權,其他使用者
  S_IWOTH:  寫入權限,其他使用者
  S_IXOTH:   運行許可權。其他使用者

傳回值:成功則返迴文件描寫敘述符。否則返回 -1。  返迴文件描寫敘述符(整型變數0~255)。由open 返回的檔案描寫敘述符一定是該進程尚未使用的最小描寫敘述符。僅僅要有一個許可權被禁止則返回-1。


錯誤碼:(均已E開頭,將其去掉就是有關於錯誤的方面的單詞或單詞的縮寫)
  EEXIST 參數pathname 所指的檔案已存在,卻使用了O_CREAT和O_EXCL旗標。
  EACCESS 參數pathname所指的檔案不符合所要求測試的許可權。


  EROFS 欲測試寫入許可權的檔案存在於僅僅讀檔案系統內。

  EFAULT 參數pathname指標超出可存取記憶體空間。

  EINVAL 參數mode 不對。
  ENAMETOOLONG 參數pathname太長。

  ENOTDIR 參數pathname不是檔案夾。
  ENOMEM 核心記憶體不足。


  ELOOP 參數pathname有過多符號串連問題。


  EIO I/O 存取錯誤。


-------------------------------------------------------------------------------------------------------------------
ssize_t write(int fd, const void *buf, size_t count);
參數:   
fd:要進行寫操作的檔案描寫敘述詞。
buf:須要輸出的緩衝區
count:最大輸出位元組計數  

傳回值:成功返回寫入的位元組數,出錯返回-1並設定errno
-----------------------------------------------.--------------------------------------------------------------------
ssize_t read(int fd, void *buf, size_t count);  
參數:      
buf:須要讀取的緩衝區
count:最大讀取位元組計數            

傳回值:成功返回讀取的位元組數,出錯返回-1並設定errno,假設在調read之前已到達檔案末尾。則這次read返回0 。  

-------------------------------------------------------------------------------------------------------------------


2、fopen庫函數
標頭檔:<stdio.h>
函數原型:FILE * fopen(const char * path, const char * mode);
path字串包括欲開啟的檔案路徑及檔案名稱,參數mode字串則代表著流形態。


mode有下列幾種形態字串:
"r"或"rb"        以僅僅讀方式開啟檔案,該檔案必須存在。
"w"或"wb"     以寫方式開啟檔案,並把檔案長度截短為零。
"a"或"ab"      以寫方式開啟檔案,新內容追加在檔案尾。
"r+"或"rb+"或"r+b"       以更新方式開啟(讀和寫)
"w+"或"wb+"或"w+b"   以更新方式開啟,並把檔案長度截短為零。


"a+"或"ab+"或"a+b"     以更新方式開啟。新內容追加在檔案尾。


字母b表示檔案時一個二進位檔案而不是文字檔。(linux下不區分二進位檔案和文字檔)
傳回值:檔案順利開啟後,指向該流的檔案指標就會被返回。假設檔案開啟失敗則返回NULL。並把錯誤碼存在errno 中。

-------------------------------------------------------------------------------------------------------------------
fread是一個函數。從一個檔案流中讀資料,最多讀取count個元素,每一個元素size位元組,假設調用成功返回實際讀取到的元素個數。假設不成功或讀到檔案末尾返回 0。
函數原型:size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;
參 數:
buffer:用於接收資料的記憶體位址
size:要讀寫的位元組數。單位是位元組
count:要進行讀寫多少個size位元組的資料項目,每一個元素是size位元組.
stream:輸入資料流
傳回值:實際讀取的元素個數.假設傳回值與count不同樣,則可能檔案結尾或錯誤發生,從ferror和feof擷取錯誤資訊或檢測是否到達檔案結尾.
-------------------------------------------------------------------------------------------------------------------
fwrite:向檔案寫入一個資料區塊
函數原型:size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
參數:
buffer:是一個指標,對fwrite來說。是要擷取資料的地址。
size:要寫入內容的單位元組數。
count:要進行寫入size位元組的資料項目的個數;
stream:目標檔案指標;
傳回值:返回實際寫入的資料區塊數目
-------------------------------------------------------------------------------------------------------------------
fflush:把檔案流裡的全部為寫出資料立馬寫出。


函數原型:int fflush(FILE *stream);
-------------------------------------------------------------------------------------------------------------------
fseek:是lseek系統調用相應的檔案流函數。它在檔案流裡為下一次讀寫操作指定位置。
函數原型:int fseek(FILE *stream, long offset, int fromwhere);
參數stream為檔案指標
參數offset為位移量,正數表示正向位移。負數表示負向位移
參數fromwhere設定從檔案的哪裡開始位移,可能取值為:SEEK_CUR、 SEEK_END 或 SEEK_SET
SEEK_SET: 檔案開頭
SEEK_CUR: 當前位置
SEEK_END: 檔案結尾
當中SEEK_SET,SEEK_CUR和SEEK_END依次為0,1和2.
傳回值:假設運行成功,stream將指向以fromwhere為基準,位移offset(指標位移量)個位元組的位置。函數返回0。假設運行失敗(比方offset超過檔案自身大小),則不改變stream指向的位置。函數返回一個非0值。

-------------------------------------------------------------------------------------------------------------------

下面為linux下一個開啟檔案並顯示檔案內容的程式:

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>char * FILE_NAME = "/home/hzg/uart/download.bin";   unsigned char file_buffer[20];int main(){    FILE * file_fd;    int read_len, i;    file_fd = fopen(FILE_NAME,"rb");    if(file_fd == NULL)    {       perror("errno");    }    else     {       printf("File Open successed!\n");    }    while(1)    {       read_len = fread(file_buffer, 1, 16, file_fd);              if(read_len == -1)       {           printf("File read error!\n");           perror("errno");           exit(0);       }       else if(read_len == 0)       {           printf("File read Over!\n");           break;       }       else        {           printf("Read %d Byte From download.bin: ",read_len);           for(i = 0; i < read_len; i++)           {                printf(" %02x",file_buffer[i]);           }           printf("\n");       }           usleep(20000);    }    fclose(file_fd);    return 0;} 

3、freopen
函數原型:FILE * freopen ( const char * filename, const char * mode, FILE * stream );
參數
filename: 要開啟的檔案名稱
mode: 檔案開啟的模式。和fopen中的模式(r/w)同樣
stream: 檔案指標,通常使用標準流檔案(stdin/stdout/stderr)
傳回值:假設成功則返回該指向該stream的指標,否則為NULL。


作用:用於重新導向輸入輸出資料流的函數。將stream中的標準輸入、輸出、錯誤或者檔案流重新導向為filename檔案裡的內容。

linux下須要重新導向輸出非常easy使用 ./程式名 >test (>>test 追加),windows下的輸入輸出重新導向能夠使用freopen。

用法: 由於檔案指標使用的是標準流檔案,因此我們能夠不定義檔案指標。

我們使用freopen()函數以僅僅讀方式r(read)開啟輸入檔案test.in 。freopen("test.in", "r", stdin);

這樣程式的輸入就會從標準輸入資料流stdin轉換到從檔案"test.in"中輸入

然後使用freopen()函數以寫入方式w(write)開啟輸出檔案test.out,freopen("test.out", "w", stdout);
程式的輸出就會從原來的標準輸出變成寫入檔案"test.out"中


Linux(C/C++)下的檔案操作open、fopen與freopen

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.