Linux程序设计:read函数、write函数

目录

read函数

write函数

典型应用案例


read函数

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
  • 返回: 读到的字节数,若已到文件尾为0,若出错为-1
  • 功能: 从打开文件中读数据
  • 对应的标准C库函数:
size_t fread (void *ptr, size_t size, size_t nmemb, FILE *stream);
  • read函数参数
fd
  • 读取文件的文件描述符
buf
  • 存放读取数据的缓存
  • 能够屏幕缓冲区中的回车符也放到buf缓冲区中(如果屏幕缓冲区中有数据,则不会阻塞,从缓冲区中取指定个数的数据放在buf中,填入buf 据时也是从头开始覆盖式填入,buf中没被覆盖的部分是不作处理的。)
count
  • 要求读取一次数据的字节数
  • 有多种情况可使实际读到的字节数少于要求读字节数
    • 读普通文件时,在读到要求字节数之前已到达了文件尾端。
    • 当从终端设备读时,通常一次最多读一行。
    • 当从网络读时,网络中的缓冲机构可能造成返回值小于所要求读的字节数。
    • 某些面向记录的设备,例如磁带,一次最多返回一个记录。
    • 进程由于信号造成中断(errno==EINTR)
  • 读操作从文件的当前位移量处开始,在成功返回之前,该位移量增加实际读得的字节数。
    • 文件指针移动实际读到的字节数(而可能不是预想读到的字节数)

write函数

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
  • 返回: 若成功为已写的字节数,若出错为-1
  • 功能: 向打开的文件中写数据
  • 对应的标准C库函数:
size_t fwrite(const void *ptr,size_t size,size t nmemb, FILE *stream);
  • write函数参数
fd
  • 写入文件的文件描述符
buf
  • 存放待写数据的缓存
  • 在这里\0相当于无字符,在内核函数中不把\0作为字符串结束的标志,只是遇到\0字符不会有显示而已,\0后的字符依旧能正确输出。
count
  • 要求写入一次数据的字节数
  • 其返回值通常与参数count的值不同,则表示出错
  • write出错的常见原因是:
    • 磁盘已写满
    • 超过了对一个给定进程的文件长度限制
  • 对于普通文件,写操作从文件的当前位移量处开始。
    • 如果在打开该文件时,指定了O_APPEND选择项,则在每次写操作之前,将文件位移量设置在文件的当前结尾处
    • 在一次成功写之后,该文件位移量增加实际写的字节数。

典型应用案例

  • 文件读写案例主要代码
#include <unistd.h>

#define BUFFER_LEN 1024
void copy(int fd1, int fd2)
{
    char buffer[BUFFER_LEN];
    ssize_t nreads;
    while((nreads = read(fd1, buffer, BUFFER_LEN)) != 0){
    if(nreads < 0){
    fprintf(stderr, "read error: %s\n", strerror(errno));
    }else{
        if(write(fd2, buffer, nreads) != nreads){
            fprintf(stderr, "read error: %s\n", strerror(errno));
         }
      }
   }
}
  • include文件夹下io.h
#ifndef _IO_H_
#define _IO_H_

extern void copy(int fdin, int fdout);

#endif
  • src文件夹下io.c
#include "io.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define BUFFER_LEN 1024
void copy(int fdin, int fdout)
{
    char buffer[BUFFER_LEN];
    ssize_t size;
    while((size = read(fdin, buffer,  BUFFER_LEN)]) > 0){
        if(write(fdout, buffer, size)!= size){
            fprintf(stderr, "write error: %s\n", strerror(errno)); 
            exit(1);
            }
    }
    if (size <0){
        fprintf(stderr, "read error: %s\n", strerror(errno));
        }
        exit(1);
    }
}
  • src文件夹下copy.c
#include "io.h"
#include <fcntl.h>
#include <unistd. h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(int argc, char * argv[])
{
	if (argc !=3){
		fprintf(stderr, "usage: %s srcfile destfile\n", argv[0]); 
		exit(1);
	}
//打开一个待读取的文件
fdin = open(argv[1], O_RDONLY);
if(fdin < 0){
	    fprintf(stderr, "open error:%s\n", strerr(errno));
	    exit(1);
	}
	else {
	    printf("open file:%d\n",fdin);
}
//打开一个待写入的文件
	fdout = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0777);
	if(fdout < 0){
	    fprintf(stderr,"open error:%s\n", strerror(errno));
	    exit(1);
    else {
	    printf("open file:%d\n",fdin);
    }
}
	//文件复制
	copy(fdin, fdout);
	close(fdin);
	close(fdout);
    return 0;
} 
  • 编译
gcc -o obj/io.o -Iinclude -c src/io.c
gcc -o bin/cp -Iinclude obj/io.o src/cp.c
  • 执行(使用编译链接后的文件的路径,避免系统自带的cp 命令)
bin/cp /etc/passwd ./passwd

猜你喜欢

转载自blog.csdn.net/baidu_41388533/article/details/108395060