文件IO(2)--read、write和lseek


      昨天我們學習了open和creat函數,今天我們繼續學習write、read和lseek函數,他們均定義在<unistd.h>。

1. read函數

1)      函數原型:

       #include <unistd.h>

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

2)      函數功能:

       read系統調用從文件描述符fd指向的文件中,讀取count個字節到buf中。

3)      參數說明:

       fd:文件描述符

       buf:保存讀入信息的緩存

      count:要讀取的字節數

      返回值:如果read成功,則返回讀到的字節數,如果已達到結尾,則返回0,出錯     

                返回-1

      

2. write函數

1)   函數原型:

         #include <unistd.h>

         ssize_t write(int fd, const void *buf, size_t count);

2)   函數功能:

       write系統調用將buf所指向的緩沖區的count個字節內容寫入fd指向的文件

3)   參數說明:

       fd:要寫入的文件

       buf:要寫入的信息所在的緩存

      count:要寫入的字節數

      返回值:如果write成功,則返回寫入的字節數,出錯返回-1

 

3. lseek函數

1)    函數原型:

       #include <sys/types.h>

       #include <unistd.h>

       off_t  lseek(int fildes, off_t offset, int whence);

2)    函數功能:

       lseek系統調用用來移動讀寫指針的位置

3)   參數說明:

       fd:要操作的文件

      offset:相對whence移動的位移數,允許負值

      whence:起始指針,它有三個取值

            SEEK_SET 從文件開始處計算偏移量

            SEEK_CUR 從文件指針的當前位置開始計算偏移量

            SEEK_END 從文件結尾處開始計算偏移量

     文件指針值等於當前指針值加上offset的值。

     返回值:調用成功時范圍當前的讀寫位置,也就是距離文件開始處多少字節,若

                有錯誤返回-1

4)  常見用法:

       將文件讀寫指針移動到文件開頭:

       lseek(int fildes, 0, SEEK_SET);

       將文件讀寫指針移動到文件結尾:

  lseek(int fildes, 0, SEEK_END);

  獲取文件讀寫指針當前的位置

  lseek(int fikdes, 0, SEEK_CUR);

注意:有些設備(或者說設備文件)不能使用lseek,linux系統不允許lseek()對tty設備進行操作,此項操作會使得lseek()范圍錯誤代碼ESPIPE

 

4.實例程序:

1)演示文件讀寫和文件指針的移動過程:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

void my_error(const char* errstring, int line)
{
    fprintf(stderr,"line:%d",line);
    perror(errstring);
    exit(1);
}

int my_read(int fd)
{
    int len = 19,ret,i;
    char buf[128];
    
    if((lseek(fd,0,SEEK_END)) == -1)
    {
        my_error("lseek",__LINE__);
    }
    if((len = lseek(fd,0,SEEK_CUR)) == -1)
    {
        my_error("lseek",__LINE__);
    }
    if((lseek(fd,0,SEEK_SET)) == -1) 
    {
        my_error("lseek",__LINE__);
    }
   
       printf("文件長:%d\n",len);
    if((ret = read(fd,buf,len)) == -1)
    {
        my_error("read",__LINE__);
    }

    for(i=0;i<len;i++)
    {
        printf("%c",buf[i]);
    }
    printf("\n");
}


int main()
{
    int fd;
    char buf[128] = "my name is haohuai!";
    umask(0000);
    if((fd = open("test.txt",O_RDWR | O_CREAT | O_TRUNC,0777)) == -1)
    {
        my_error("open",__LINE__);
    }
    else
    {
        printf("open success!\n");
    }
    
    if(write(fd,buf,strlen(buf)) != strlen(buf))
    {
        my_error("write",__LINE__);
    }
    else
    {
        printf("write success!\n");
    }
    my_read(fd);
    return 0;

}

注:1)其中__LINE__是預編譯器內置宏,表示當前行,類似的還有__TIME__、

    __FUNCTION__ 、__FILE__等,表示時間、函數名、文件名。

    2)read讀取文件之前一定要先將文件指針指向文件開始處,否則文件指針處

    於文件結尾處。

運行結果:

[hb@localhost unixadvance]$ gcc -g -o testWRL testWRL.c

[hb@localhost unixadvance]$ ./testWRL

open success!

write success!

文件長:19

my name is haohuai!

 

2)將標准輸入復制到標准輸出

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#define SIZE 1024

int main()
{
    int n ;
    char buf[SIZE];

    while((n = read(STDIN_FILENO,buf,SIZE)) > 0)
    {
        if(write(STDOUT_FILENO,buf,n) != n)
        {
            perror("write error");
        }
    }
    if(n < 0)
    {
        perror("read error");
    }

    return 0;
}

注:STDIN_FILENO和STDOUT_FILENO分別是標准輸入和標准輸入的文件描述

   符,一般是0和1,定義在<unistd.h>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM