• read()和write()


    读函数read

    ssize_t read(int fd,void *buf,size_t nbyte) 

    作用:从文件描述符(fildes)相关联的文件里读入nbytes个字节的数据,并把它们放到数据区buf中。
               read返回实际读入的字节数,这可能会小于请求的字节数,如果read调用返回0,表示未读入任
               何数据,已到达了文件尾;如果返回-1,表示read调用出现了错误。
     

     1 #include <stdio.h>
     2 #include <unistd.h>
     3 
     4 int main(void)
     5 {
     6     char buffer[128];
     7     int nread;
     8 
     9     nread = read(0, buffer, 128);
    10     if (-1 == nread)
    11          write(2, "A read error has occurred
    ", 26);
    12 
    13     if ( (write(1, buffer, nread)) != nread )
    14          write(2, "A write error has occurred
    ", 27);
    15 
    16     return 0;
    17 }
    18                 

     

    写函数write 

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

    作用:把缓冲区(buf)的前nbytes个字节写入与文件描述符(fildes)关联的文件。
               write返回实际写入的字节数,如果文件描述符有错误或者底层设备的驱动程序对数据长度比
               较敏感,表示在write调用中出现了错误,返回值可能会小于nbytes。如果函数返回0,表示
               未写入任何数据;返回-1表示write调用中出现了错误,错误代码保存在全局变量errno中。

    write可能会报告写入的字节比要求的少,这不一定时错误,在程序中,需要检查errno以发现
    错误,然后再次调用write写入剩余数据

     1 #include <stdio.h>
     2 #include <unistd.h>    // write调用原型所在的头文件
     3 
     4 int main(void)
     5 {
     6     if ( (write(1, "Here is some data
    ", 18)) != 18 )
     7     write(2, "A write error has occurred on file descriptor 1
    ", 46);
     8 
     9     return 0;
     10}

    read和write函数在字节流套接字上表现的行为和通常的文件I/O不同,字节流套接字上调用
    read和write输入或输出的字节数可能比请求的数量少,然而这不是出错状态。这个现象的原
    因在于内核用于套接字的缓冲区可能已达到了极限,此时需要多次调用read和write函数,以
    输入或输出剩余字节。

    《Unix 网络编程》中用于在字节流套接字上的读写函数

     1 ssize_t readn(int fd, void *vptr, size_t n)
     2 {
     3     size_t nleft;
     4     ssize_t nread;
     5     cahr *ptr;
     6     ptr = vptr;
     7     nleft = n;
     8 
     9     while (nleft > 0)
    10     {
    11         if ( (nread = read(fd, ptr, nleft)) < 0 )
    12         {
    13             if (errno == EINTR)
    14                 nread = 0;
    15             else
    16                 return -1;
    17         }
    18         else if (nreda == 0)
    19         {
    20             break;
    21         }
    22 
    23         nleft -= nread;
    24         ptr += nread;
    25     }
    26 
    27     return (n - nleft);
    28 }
    29 
    30 ssize_t writen(int fd, const void *vptr, size_t n)
    31 {
    32     size_t nleft;
    33     ssize_t nwritten;
    34     const char *ptr;
    35     ptr = vptr;
    36     nleft = n;
    37     while (nleft > 0)
    38     {
    39         if ( (nwritten = write(fd, ptr, nleft)) <= 0 )
    40         {
    41             if (nwritten < 0 && errno == EINTR)
    42                 nwritten = 0;
    43             else
    44                 return -1;
    45         }
    46 
    47         nleft -= nwritten;
    48         ptr += nwritten;
    49     }
    50 
    51     return n;
    52 }
    53 
    54 ssize_t readline(int fd, void *vptr, size_t maxlen)
    55 {
    56     ssize_t n, rc;
    57     cahr c, *ptr;
    58     ptr = vptr;
    59 
    60     for (n = 1; n < maxlen; n++)
    61     {
    62     again:
    63         if ( (rc = read(fd, &c, 1)) == 1 )
    64         {
    65             *ptr++ = c;
    66             
    67             if (c == '
    ')
    68                 break;
    69         }
    70         else if (rc == 0)
    71         {
    72             *ptr = 0;
    73             return (n -1);
    74         }
    75         else
    76         {
    77             if (errno == EINTR)
    78                 goto again;
    79             return -1;
    80         }
    81     }
    82 
    83     *ptr = 0;
    84 
    85     return n;
    86 }
  • 相关阅读:
    洛谷-P2430 严酷的训练
    Hackthebox网络不稳定的解决方案
    解压
    谷歌地图API密钥未授权利用
    关于读取heapdump踩的一个小坑
    RECON
    最近思考
    go get
    Js跳转
    Session
  • 原文地址:https://www.cnblogs.com/lnlin/p/9492144.html
Copyright © 2020-2023  润新知