函数read、write、lseek

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/isunbin/article/details/83472842

函数原型: 

#include<unistd.h>
ssize_t read(int fd, void *buf, size_t count);
                                       返回值:读到的字节数,若已到文件尾,返回0;若出错,返回-1

参数:

  • fd:函数open的返回值
  • buf:缓冲区,存储要读取的数据
  • count:缓冲区的最大字节数size(buf)

函数原型:

#include<unistd.h>
sszie_t write(int fd, const void *buf, size_t count);
                          返回值:若成功,返回已写的字节数,若出错,返回-1

参数:

  • fd:函数open返回值
  • buf:要写到文件的数据
  • count:strlen(buf)

测试代码:

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

int main(int argc, const char* argv[])
{
    int fd = open("english.txt", O_RDWR);
    printf(" fd = %d\n", fd);

    int fd1 = open("temp", O_WRONLY | O_CREAT, 0664);
    printf("fd1 = %d\n",fd1);

    char buf[4096];
    int len = read(fd, buf, sizeof(buf));

    while(len > 0) {

        int ret = write(fd1, buf, len);
        printf("ret = %d\n", ret);

        len = read(fd, buf, sizeof(buf));
    }

    close(fd);
    close(fd1);
    return 0;
}

输出结果:

函数原型:
 

#include<unistd.h>
off_t lssk(int fd, off_t offset, int whence);
                                          返回值:若成功, 返回新的文件的偏移量;若出错,返回-1

参数:

  • 若whence是SEEK_SET,则将该文件的偏移量设置为距文件的开始处offset个字节。
  • 若whence是SEEK_CUR,则将该文件的偏移量设置为当前值加offset,offset可正可负。
  • 若whence是SEEK_END,则将该文件的偏移量设置为文件长度加offset,offset可正可负。

使用:

  • 文件指针移动到头部:lseek(fd, 0, SEEK_SET);
  • 获取文件指针当前位置:int len = lseek(fd, 0, SEEK_CUR);
  • 获取文件长度:int len = lseek(fd, 0, SEEK_END);
  • 文件拓展:文件原大小100k,拓展为1100k。lseek(fd, 1000, SEEK_END); 最后一次写操作:write(fd, "a", 1);

测试代码:

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

int main(int argc, const char *argv[])
{
    int fd = open("english.txt", O_RDWR);
    if(fd == -1) {
        perror("open error");
        exit(1);
    }

    int len = lseek(fd, 1000, SEEK_END);
    printf("len = %d\n", len);

    write(fd, "a", 1);
    close(fd);
    return 0;
}


输出结果:

阻塞与非阻塞

阻塞和非阻塞是文件的属性还是read函数的属性? 答案:文件的属性

  • 普通文件:hello.c 不阻塞
  • 终端设备:/dev/tty、管道、套接字:,默认阻塞

1. 阻塞读终端

测试代码:

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

int main()
{
    char buf[10];
    int n;
    n = read(STDIN_FILENO, buf, 10);
    if(n < 0) {
        perror("read STDIN_FILENO");
        exit(1);
    }

    write(STDOUT_FILENO, buf, n);
    return 0;
}

输出结果:

分析:

测试代码:

#include <unistd.h> 
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#define MSG_TRY "try agin\n"

int main()
{
    char buf[10];
    int fd, n;
    // /dev/tty --->当前打开的终端设备
    fd = open("/dev/tty", O_RDONLY | O_NONBLOCK);
    if(n < 0) {
        perror("open /dev/tty");
        exit(1);
    }
    tryagin:
        n = read(fd, buf, 10);
        if(n < 0) {
            //如果write为非阻塞,但是没有数据可读,此时全局变量errno被设置为EAGAIN
            if(errno == EAGAIN) {
                sleep(3);
                write(STDOUT_FILENO, MSG_TRY, strlen(MSG_TRY));
                goto tryagin;
            }
            perror("read /dev/tty");
            exit(1);
        }
        write(STDOUT_FILENO, buf, n);
        close(fd);
        return 0;
}

输出结果:

猜你喜欢

转载自blog.csdn.net/isunbin/article/details/83472842