天天看點

linux檔案操作函數(open、write、read、close)

1. open()函數

功能描述:用于打開或建立檔案,在打開或建立檔案時可以指定檔案的屬性及使用者的權限等各種參數。

所需頭檔案:#include <sys/types.h>,#include <sys/stat.h>,#include <fcntl.h>

函數原型:int open(const char *pathname,int flags,int perms)

參數:

pathname:被打開的檔案名(可包括路徑名如"dev/ttyS0")

flags:檔案打開方式,

O_RDONLY:以隻讀方式打開檔案

O_WRONLY:以隻寫方式打開檔案

O_RDWR:以讀寫方式打開檔案

O_CREAT:如果改檔案不存在,就建立一個新的檔案,并用第三個參數為其設定權限

O_EXCL:如果使用O_CREAT時檔案存在,則傳回錯誤消息。這一參數可測試檔案是否存在。此時open是原子操作,防止多個程序同時建立同一個檔案

O_NOCTTY:使用本參數時,若檔案為終端,那麼該終端不會成為調用open()的那個程序的控制終端

O_TRUNC:若檔案已經存在,那麼會删除檔案中的全部原有資料,并且設定檔案大小為0

O_APPEND:以添加方式打開檔案,在打開檔案的同時,檔案指針指向檔案的末尾,即将寫入的資料添加到檔案的末尾

O_NONBLOCK: 如果pathname指的是一個FIFO、一個塊特殊檔案或一個字元特殊檔案,則此選擇項為此檔案的本次打開操作和後續的I/O操作設定非阻塞方式。

O_SYNC:使每次write都等到實體I/O操作完成。

O_RSYNC:read 等待所有寫入同一區域的寫操作完成後再進行

在open()函數中,falgs參數可以通過“|”組合構成,但前3個标準常量(O_RDONLY,O_WRONLY,和O_RDWR)不能互相組合。

perms:被打開檔案的存取權限,可以用兩種方法表示,可以用一組宏定義:S_I(R/W/X)(USR/GRP/OTH),其中R/W/X表示讀寫執行權限,

USR/GRP/OTH分别表示檔案的所有者/檔案所屬組/其他使用者,如S_IRUUR|S_IWUUR|S_IXUUR,(-rex------),也可用八進制800表示同樣的權限

傳回值:

成功:傳回檔案描述符

失敗:傳回-1

2. close()函數

功能描述:用于關閉一個被打開的的檔案

所需頭檔案: #include <unistd.h>

函數原型:int close(int fd)

參數:fd檔案描述符

函數傳回值:0成功,-1出錯

3. read()函數

功能描述: 從檔案讀取資料。

所需頭檔案: #include <unistd.h>

函數原型:ssize_t read(int fd, void *buf, size_t count);

參數:  

fd: 将要讀取資料的檔案描述詞。

buf:指緩沖區,即讀取的資料會被放到這個緩沖區中去。

count: 表示調用一次read操作,應該讀多少數量的字元。

傳回值:傳回所讀取的位元組數;0(讀到EOF);-1(出錯)。

以下幾種情況會導緻讀取到的位元組數小于 count :

    A. 讀取普通檔案時,讀到檔案末尾還不夠 count 位元組。例如:如果檔案隻有 30 位元組,而我們想讀取 100

位元組,那麼實際讀到的隻有 30 位元組,read 函數傳回 30 。此時再使用 read 函數作用于這個檔案會導緻 read 傳回 0 。

    B. 從終端裝置(terminal device)讀取時,一般情況下每次隻能讀取一行。

    C. 從網絡讀取時,網絡緩存可能導緻讀取的位元組數小于 count位元組。

    D. 讀取 pipe 或者 FIFO 時,pipe 或 FIFO 裡的位元組數可能小于 count 。

    E. 從面向記錄(record-oriented)的裝置讀取時,某些面向記錄的裝置(如錄音帶)每次最多隻能傳回一個記錄。

    F. 在讀取了部分資料時被信号中斷。

讀操作始于 cfo 。在成功傳回之前,cfo 增加,增量為實際讀取到的位元組數。

4. write()函數

功能描述: 向檔案寫入資料。

所需頭檔案: #include <unistd.h>

函數原型:ssize_t write(int fd, void *buf, size_t count);

傳回值:寫入檔案的位元組數(成功);-1(出錯)

功能:write 函數向 filedes 中寫入 count 位元組資料,資料來源為 buf 。傳回值一般總是等于 count,否則就是出錯了。常見的出錯原因是磁盤空間滿了或者超過了檔案大小限制。

對于普通檔案,寫操作始于 cfo 。如果打開檔案時使用了 O_APPEND,則每次寫操作都将資料寫入檔案末尾。成功寫入後,cfo 增加,增量為實際寫入的位元組數。

5. lseek()函數 

功能描述: 用于在指定的檔案描述符中将将檔案指針定位到相應位置。

所需頭檔案: #include <unistd.h>,#include <sys/types.h>

函數原型:off_t lseek(int fd, off_t offset,int whence);

參數:

fd;檔案描述符

offset:偏移量,每一個讀寫操作所需要移動的距離,機關是位元組,可正可負(向前移,向後移)

whence:

SEEK_SET:目前位置為檔案的開頭,新位置為偏移量的大小

SEEK_CUR:目前位置為指針的位置,新位置為目前位置加上偏移量

SEEK_END:目前位置為檔案的結尾,新位置為檔案大小加上偏移量的大小

傳回值:

成功:傳回目前位移

失敗:傳回-1

6.函數執行個體1

#include <stdio.h>

#include <string.h>

#include <stdlib.h>  

#include <unistd.h>

#include <fcntl.h>

#include<sys/types.h>

#include<sys/stat.h>

#include <errno.h>

#define BUFFER_SIZE 128                               //每次讀寫緩存大小,影響運作效率

#define SRC_FILE_NAME "src_file.txt"              //源檔案名

#define DEST_FILE_NAME "dest_file.txt"          //目标檔案名

#define OFFSET 0                                             //檔案指針偏移量

int main()

{

      int src_file,dest_file;

      unsigned char src_buff[BUFFER_SIZE];

      unsigned char dest_buff[BUFFER_SIZE];

      int real_read_len = 0;

      char str[BUFFER_SIZE] = "this is a testabout\nopen()\nclose()\nwrite()\nread()\nlseek()\nend of the file\n";

      //建立源檔案

      src_file=open(SRC_FILE_NAME,O_RDWR|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);  

      if(src_file<0)

      {

            printf("open file error!!!\n");

            exit(1);

      }

     //向源檔案中寫資料

    write(src_file,str,sizeof(str));

     //建立目的檔案

     dest_file=open(DEST_FILE_NAME,O_RDWR|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);  

      if(dest_file<0)

      {

          printf("open file error!!!\n");

            exit(1);

      }

      lseek(src_file,OFFSET,SEEK_SET);//将源檔案的讀寫指針移到起始位置

      while((real_read_len=read(src_file,src_buff,sizeof(src_buff)))>0)

      {

        printf("src_file:%s",src_buff);

            write(dest_file,src_buff,real_read_len);

      }

    lseek(dest_file,OFFSET,SEEK_SET);//将目的檔案的讀寫指針移到起始位置

    while((real_read_len=read(dest_file,dest_buff,sizeof(dest_buff)))>0);//讀取目的檔案的内容

    printf("dest_file:%s",dest_buff);

      close(src_file);

      close(dest_file);

      return 0;

}

結果 如下:

src_file:this is a test about

open()

close()

write()

read()

lseek()

end of the file

dest_file:this is a test about

open()

close()

write()

read()

lseek()

end of the file

函數執行個體2

#include <stdio.h>

#include <string.h>

#include <stdlib.h>  

#include <unistd.h>

#include <fcntl.h>

#include<sys/types.h>

#include<sys/stat.h>

#include <errno.h>

#define BUFFER_SIZE 1024

#define OFFSET 0                          //檔案指針偏移量

#define IP_FILE "ip.txt"

int creat_fd,write_fd,open_fd;

char readbuf[BUFFER_SIZE];

char writebuf[]="192.168.1.1";

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

{

int ret=1;

int file_len=0;

#if 0

/* 導入參數 */

//para1:command name para2:filename

if (argc != 2)

{

printf("argc number error!need 2,support %d\n",argc);

exit(1);

}

#endif

//creat file

creat_fd=open(IP_FILE,O_RDWR|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); 

if(creat_fd<0)

      {

        printf("creat serverip file error!!!\n");

        exit(1);

      }

//write data to file

write_fd=write(creat_fd,writebuf,sizeof(writebuf));

if(write_fd<0)

      {

        printf("write data to serverip.txt error!!!\n");

        exit(1);

      }

//open file

//open_fd= open(argv[1],O_RDWR);

open_fd= open(SERVERIP_FILE,O_RDWR);

if(open_fd<0)

{

printf("read file error!!!\n");

exit(1);

}

//測量檔案大小

//off_t lseek(int fd, off_t offset,int whence);

file_len=lseek(open_fd,OFFSET,SEEK_END);//傳回值為檔案大小+offset

lseek(open_fd,OFFSET,SEEK_SET);         //重定位檔案開始

printf("file size=%d\n",file_len);

//read file

//ssize_t read(int fd, void *buf, size_t count); 

//檔案讀寫位置會随讀取到的位元組移動,如果傳回0,表示已到達檔案尾或是無可讀取的資料

while(ret)

{

ret=read(open_fd,readbuf,BUFFER_SIZE);

if(ret == -1)

{

printf("read file error!!!\n");

exit(1);

}

file_len-=ret;

}

printf("there are %d byte(s) data left without read\n", file_len);

printf("%s\n",readbuf);

//close file 

close(open_fd);

return 0;

}