Linux-文件操作(open、write、read、close、iotcl)

首先,介紹一下linux環境下簡單c程序的執行與運行,就以HelloWorld爲例。

  1. 建立並編寫一個.c文件。
    命令:touch helloWorld.c
    編寫文件內容:vim helloWorld.c(當然,也可以用emacs,個人不喜歡emacs)
    文件中的內容:
#include <stdio.h>
#include <stdlib.h>

int main(){
  printf("Hello World!\n");
  exit(0);
}
  1. 編譯運行。
    編譯命令:gcc -o helloWorld helloWorld.c
    運行命令:./helloWorld
    結果:helloWorld運行結果

以上就是一個簡單的linuc c程序的建立與運行,非常簡單,下面來學習linux c中關於文件的操作。


首先分析以下常用的文件路徑

  • 應用程序
    系統提供的應用程序的路徑一般在/usr/bin或/usr/local/bin中

  • 頭文件
    基本頭文件在/usr/include,附加頭文件一般在/usr/include/sys或/usr/include/linux中。
    使用gcc -I的選項可以引入不在默認路徑中的頭文件。
    例如:$gcc -I /usr/openwin/include hello.c

  • 庫文件
    標準庫文件一般在/lib或/usr/lib
    庫文件可以分爲靜態庫(.a)和共享庫(.so)
    庫文件的命名規範:以lib開頭,後面部分指明庫功能,後綴名說明庫類型。
    gcc的-l選項可以指定要搜索的庫文件,-L選項指定庫路徑。
    例如:gcc -o hello hello.c /usr/lib/libm.a
    gcc -o hello hello.c -lm
    gcc -o hello hello.c -L .usr/lib -l /usr/temp/lib/x.a


文件路徑介紹完,正式進入文件的操作!!
系統調用的概念:
Linux只需要少量函數就可以實現對文件和設備的訪問和控制,這些函數被成爲系統調用。
系統調用由Linux系統直接提供,是通向操作系統自身的接口。
Linux系統提供5個系統調用:open,write,read,close,iotcl
硬件的特有功能一般通過系統調用iotcl來完成。

  • write系統調用
    系統調用原型:
#include <unistd.h>
size_t write(int fildes,const void *buf,size_t nbytes);

功能詳解:將緩衝區buf的前nbytes個字節寫入文件描述符fildes關聯的文件中,返回實際寫入的字節數(如果fildes大小不夠或者有錯返回將小於nbytes,返回0表示未寫入任何數據,返回-1表示寫入過程錯誤)
例子:

#include <unistd.h>
#include <stdlib.h>

int main()
{
    if((write(1,"Here is some data\n",18)) != 18)
        write(2,"A write error has occurred on file descriptor 1\n",46);
    exit(0);
}

這裏寫圖片描述

  • read系統調用
    系統調用原型:
#include <unistd.h>
size_t read(int fildes,void *buf,size_t nbytes);

功能詳解:
從文件描述符fildes關聯的文件中讀入nbytes個字節,並放入緩衝區buf中,返回實際讀入的字節數(有可能小於nbytes,返回0表示未讀入任何數據或者已經到文件尾,返回-1表示錯誤)。
例子:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(){
   char buffer[128];
   int nread;
   nread = read(0, buffer, 128);
   if(nread == -1)
       write(2,"A read error has occurred\n",26);
   if((write(1,buffer,nread)) != nread)
       write(2,"A write error has occurred\n",27);
   printf("Hello\n");
   exit(0);
}

結果:
這裏寫圖片描述

  • open系統調用
    系統調用原型:
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 int open(const char *path,int oflags);
 int open(const char *path,int oflags,mode_t mode);

功能詳解:
open系統調用創建一個新的文件描述符,如果調用成功將返回一個可以被read/write和其他系統調用使用的文件描述符。準備打開的設備或文件作爲參數path傳給函數,oflags參數用於指定文件打開所採取的動作。

  • close系統調用和ioctl系統調用
    系統調用原型:

close:

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

ioctl:

#include <unistd.h>
int ioctl(int fildes,int cmd,...);

例子:打開led燈

ioctl(tty_fd,KDSETLED,LED_NUM|LED_CAP|LED_SCR);

結合使用例子:
1.文件複製

#include <unistd.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main()
{
    char c;
    int in,out;
    in = open("file.in",O_RDONLY);
    out = open("file.out",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);

    while(read(in,&c,1) == 1)
      write(out,&c,1);
    exit(0);
}

下面是優化的代碼:

#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

int main()
{
    char block[1024];
    int in,out;
    int nread;
    in = open("file.in",O_RDONLY);
    out = open("file.out",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
    while((nread == read(in,block,sizeof(block))) > 0)
       write(out,block,nread);
    exit(0);
}

優化的原理是,每次複製1個字符改爲每次複製1024個字符。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章