解析標準IO中對文件的基本操作

  對于Linux程序員來說,對文件的IO操作是應用編程的基礎內容,也是必須掌握的技能;下面作者通過兩個基本概念和四個函數,來解析對文件的基本操作;

  首先要明白兩個基本的概念;文件和IO;

  1.文件:文件指的是同類型數據的集合; 在linux中有一個重要思想;一切皆文件;也是說在Linux系統中把所有的文件、設備、內存等都當做文件來看待;因為這個思想的存在,所有在Linux系統中對設備及文件的操作方式都是一樣的。Linux中把文件分為七種類型,分別是普通文件、設備文件(塊設備和字符設備)、目錄文件、管道文件、鏈接文件(符號鏈接文件),套接字;我們主要以普通文件來學習;

  2. IO: IO是input和output的簡寫,也就是指的輸入和輸出;對于Linux系統來講;輸入及輸出主要是從程序的角度來看的,因為程序員的主要的工作就是使用程序來處理數據; 所以輸入指的就是把數據輸入到程序中,輸出值指的是從程序中輸出數據;一般情況下,輸入主要使用鍵盤,鍵盤也叫標準輸入,而輸出的結果主要顯示在屏幕上,屏幕也就是標準輸出;除了標準輸入和標準輸出外,還有一個標準文件——標準錯誤輸出,它指的是當程序與運行或出錯時,結果也會顯示到屏幕上; 實際中,我們的數據輸入并不一定要從鍵盤中輸入,輸出也不是只能輸出到屏幕上;我們可以從文件、內存中輸入數據到程序,也可以從程序中輸出數據到文件及內存中;

  在此文中,輸入/輸出都是對文件而言;

  了解上面兩個概念的有什么作用呢?作用就是你了解了我們操作對象是——文件;同時了解對文件進行的操作——數據的輸入及輸出;

  那么,我們操作文件的一般思路是什么?思考1分鐘鐘再往下看!

  操作一個文件時無非就以下三個步驟:

  第一:打開文件;

  第二:操作文件;

  第三:關閉文件;

  就是這么簡單,你在之前的生活經歷中早就掌握文件的操作思路了;問題在于,在Linux中,怎么打開、操作、關閉文件?答案是用對應的函數操作,所以IO的學習除了了解基本概念外,就是學習函數的的使用。

  我先以標準IO 為例:我們通過四個函數來解析基本的操作思路;

  標準IO中打開文件用 fopen()函數;原型為 FILE *fopen(const char *path, const char *mode);從原型中可以看出,fopen()有兩參數;形參const char *path對應就是我需要打開的文件名稱,包括文件的路徑名稱;const char *mode指的是打開文件后我們要對文件進行項什么樣的操作? 是讀、寫、還是添加的寫?參數如下:

  mode 的參數有一些固定值;

  r ——只讀方式打開,

  r+ ——讀寫方式打開,

  以上兩個參數必須要求文件存在;

  w ——只寫方式打開,

  w+ ——讀寫方式打來;

  使用以上兩個參數時;若文件存在,則會清空文件,再寫入具體數據!若文件不存在,則創建文件再寫入數據;

  a —— 以只寫方式打開;

  a+ —— 以讀寫方式打開;

  以上兩個參數使用時,若文件存在,則在后面添加數據,若文件不存在,則創建再寫入數據;

  上面的6個參數就是mode 可以寫入的全部值;(都是單獨使用的)

  在fopen前有一個FILE *; 它是什么呢?當我們創建一個打開一個文件時,就會創建一個FILE 結構體描述改文件,或者說是創建一個FILE文件結構體和實際的文件關聯起來;之后對FILE * 變量的操作就是對文件的操作;FILE 結構體也稱為流;

  標準IO關閉文件的函數是 fclose()函數,原型為:int fclose(FILE *fp);

  只要把對應的文件流變量傳給fclose()就可以了;

  我們先來看一個fopen()函數的例子;

  #include

  int main(int argc,char *argv[])

  {

  FILE *fp;

  if(argc !=2)

  {

  printf("usage %s \n",argv[0]);

  exit(1);

  }

  fp = fopen(argv[1],"w");

  if(fp == NULL)

  {

  perror("perror");

  exit(1);

  }

  fclose(fp);

  return 0;

  }

  上面就是一個最簡單的打開文件的程序;

  接下來要做的事就是怎么去操作文件?

  文件的操作分兩種方式,對文件進行讀,或者對文件進行寫!

  讀寫的函數比較多,作者以fgets()和fputs()為例來講解如何對文件進行讀寫操作;首先是fgets(); 它的主要作用是從文件流中讀取數據,原型: char *fgets(char *s, int size, FILE *stream);對應的參數從后往前看,FILE *stream 指的是要讀取的文件流,也會是要從此文件中讀取數據;每次讀的大小對應 int size ,并把數據存放到 char *s 對應的地址,成功會返回讀到的字節數, 失敗返回NULL;

  下面時fgets()的實例程序:

  #include

  #include

  int main(int argc, char *argv[])

  {

  FILE *fp;

  char buf[20];

  if(argc !=2)

  {

  printf("usage %s \n",argv[0]);

  exit(1);

  }

  fp = fopen(argv[1],"r");

  if(fp == NULL)

  {

  perror("fopen failed");

  exit(1);

  }

  while (fgets(buf, 20, fp) !=NULL)

  {

  printf("%s",buf);

  }

  fclose(fp);

  return 0;

  }

  上面的程序中關于fgets()使用, 程序每次從fp對應的文件中讀取19個字節數據并存在在buf中,并且在屏幕上打印出來;直到數據讀完為止;

  那么,如果想從一個文件中讀取數據并寫到另一個文件中,該怎么做?這就可以在上面的程序基礎上添加一個函數的fputs();它的原型:int fputs(const char *s, FILE *stream); 對應的參數FILE *stream 是被寫入的文件,也就是把數據寫入此文件中;const char *s 是需要寫入的數據; 實現從一個文件中讀取數據并寫到另一個文件中的程序就可以這樣做;

  #include

  #include

  int main(int argc,char *argv[])

  {

  FILE *read_fp,*write_fp;

  char buf[10];

  if(argc !=3)

  {

  printf("usage %s \n",argv[0]);

  exit(1);

  }

  read_fp = fopen(argv[1],"r");

  if(read_fp == NULL)

  {

  perror("read_fopen failed");

  exit(1);

  }

  write_fp = fopen(argv[2],"w");

  if(write_fp == NULL)

  {

  perror("write_fp fopen failed");

  exit(1);

  }

  while(fgets(buf, 10, read_fp) !=NULL)

  {

  fputs(buf, write_fp);

  }

  fclose(read_fp);

  fclose(write_fp);

  return 0;

  }

  通過上面的概念及函數的使用,我們解析了標準IO中對文件的基本操作,當然,對文件的操作函數還有很多,但操作思路基本一樣;讀者可以以此為突破口進行更深入的學習。

the end

評論(0)