IO进程 day02

5. 标准IO

5.6. 标准IO函数接口(下)

5.6.1. fread/fwrite

fread

#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

 功能:从指定类型的文件中读取内容
 参数:
  void* ptr:存放读取内容首地址
  size_t size:读取一个元素内容的字节大小,一次读多少字节
  size_t nmemb:读取的元素个数
  FILE* stream:流指针,指向目标文件
 返回值:
  成功返回读取的元素个数,读到文件末尾则返回0
  失败返回-1
fwrite

#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

 功能:向指定的文件中写内容
 参数:
  ptr:向文件中写的内容的首地址
  size:写入的元素内容的字节大小,一次写多少个字节
  nmemd:写入的元素个数
  stream:流指针,指向目标文件
 返回值:
  成功返回写入的元素个数
  失败返回-1
练习
将一个int类型的数组写到文件中保存,并且读出来

#include <stdio.h>

int main(int argc, char const *argv[])
{
    FILE *fp = NULL;
    int arr[5] = {1, 2, 3, 4, 5};
    int str[5] = {};

    // 打开文件
    fp = fopen("./file1.c", "w+");
    if (fp == NULL)
    {
        perror("open err");
        return EOF;
    }

    // 写入文件
    fwrite(arr, sizeof(int), 5, fp);
    // 移动文件指针
    fseek(fp, 0, SEEK_SET);
    // 读文件
    fread(str, sizeof(int), 5, fp);
    for (int i = 0; i < 5; i++)
        printf("%-4d", str[i]);
    // 关闭文件
    fclose(fp);
    fp = NULL;

    return 0;
}

5.6.2. 文件指针偏移函数

rewind
#incldue <stdio.h>
void rewind (FILE *stream)

 功能:将文件指针移动到文件开头
 参数:流指针,指向打开的文件

ftell
#include <stdio.h>
long ftell(FILE *stream);

 功能:计算文件指针当前所在位置,相对于文件开头
 参数:流指针,指向打开的文件
 返回值:成功返回文件指针所在位置,失败返回-1,并更新errno

fseek
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);

 功能:将文件指针偏移到指定位置
 参数:
  stream:流指针,指向目标文件
  offset:偏移量:
   +5向后偏移5个字节
   -5向前偏移5个字节
  whence:相对位置
   SEEK_SET:文件开头
   SEEK_CUR:文件指针当前位置
   SEEK_END:文件结尾
 返回值:成功返回0,失败返回-1,更新errno

6. 文件IO

6.1. 概念

 内核向上提供的输入输出函数接口,叫做系统调用函数接口。基于内核,内核不同,系统调用函数接口不同,文件IO不同操作系统函数接口不通用。可移植性较差。

6.2. 文件IO的特点

在这里插入图片描述
1. 没有缓存机制,每次调用都引起系统调用
2. 围绕文件描述符进行操作,文件描述符都是非负整数,依次进行分配
3. 文件IO默认打开三个文件描述符,0(标准输入),1(标准输出),2(标准出错)
4. 文件IO可以操作除了目录文件之外的任意类型的文件

6.3. 文件IO的函数接口

posix 规范 Linux发展的标准

6.3.1. open/close

open

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);

 功能:打开文件
 参数:
  pathname:文件路径名
  flags:打开文件方式
 返回值:成功返回文件描述符,失败返回-1;

文件打开方式对应权限
O_RDONLY只读
O_WRONLY只写
O_RDWR可读可写
O_CREAT创建
O_TRUNC清空
O_APPEND追加

注意
当参数中出现O_CREAT(创建)时,函数定义变为

int open(const char *pathname, int flags, mode_t mode);

 mode:创建文件的权限,权限的算法:mode &~umask
 umask:文件权限掩码,值为0002
 权限掩码可修改:
  查看权限掩码:umask  修改文件权限掩码:umask 0000
 修改后的权限掩码可以与mode保持一致
fopen和open的不同的打开方式
r:O_RDONLY
r+ : O_RDWR
w : O_WRONLY | O_CREAT | O_TRUNC,0666
w+ :O_RDWR | O_CREAT | O_TRUNC,0666
a : O_WRONLY | O_APPEND | O_CREAT,0666
a+ : O_RDWR | O_APPEND | O_CREAT,0666
close

 #include <unistd.h>
 int close(int fd);

 功能:关闭文件

6.3.2. read/write

read

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

 功能:读文件
 参数:
  fd:文件描述符
  buf:存放内容的首地址
  count:期待读取到的字符个数
 返回值:
  成功返回实际读取到的字符个数,读到文件结尾返回0
  失败返回-1,并更新errno
注意
read读文件时count是多少就读多少,不会自动补‘\0’,遇到\n也不会自动停止,会继续读取下一行的内容。所以需要预留一个\0的位置
使用技巧

  1. 通过返回值作为实际读到的字符个数
char buf[32];
ssize_t ret = read(fd, buf, 31);
buf[ret] = '\0';
  1. 每次读取到的内容放到数组之前先清空数组

write

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

 功能:写文件
 参数:
  fd:文件描述符
  buf:写入内容的首地址
  count:期待写入到的字符个数
 返回值:
  成功返回实际写入的字符个数
  失败返回-1,并更新errno
读多少写多少

ssize_t ret = read(fd1,buf,64);
write(fd2,buf,ret);

练习

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#define N 32

int main(int argc, char const *argv[])
{
	int fd1 = -1;
	int fd2 = -1;
    char buf[N] = {};
    ssize_t ret = 0;
    
	// 命令行传参判错
    if (argc != 3)
    {
        perror("argc err");
        return -1;
    }
    
	// 以只读的方式打开文件fd1
    fd1 = open(argv[1], O_RDONLY);
    if (fd1 == -1)
    {
        perror("open fd1 err");
        return -1;
    }
    
    // 以只写的方式打开fd2
    fd2 = open(argv[2], O_WRONLY);
    if (fd2 == -1)
    {
        perror("open fd2 err");
        return -1;
    }

    // 读多少写多少
    while (ret = read(fd1, buf, sizeof(buf)))
        ret = write(fd2, buf, ret);

    close(fd1);
    close(fd2);

    return 0;
}

6.3.3. lseek

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);

 功能:将文件指针偏移到指定位置
 参数:
  fd:文件描述符
  offset:偏移量: +:向后 -:向前
  whence:相对位置
   SEEK_SET:文件开头
   SEEK_CUR:当前位置
   SEEK_END:文件结尾
 返回值:
  成功基于文件开头返回当前位置
  失败返回-1,更新errno

标准IO和文件IO的区别

标准IO文件IO
概念C库定义的用于输入输出的函数系统中定义的用于输入输出的函数
特点1. 有缓冲机制
2. 围绕流进行操作,FILE*
3. 默认打开三个流:stdout/stdin/stderr
1. 无缓冲机制
2. 围绕文件标识符进行操作,非负整数
3. 默认分配三个文件标识符,0,1,2
4. 可以操作除目录文件外所有文件
函数打开关闭文件:fopen/fclose
读写:fgetc/fputc;fgets/fputs;fread/fwrite
定位:fseek/rewind/ftell
时间:time/loacltime
其他:fflush/fprintf/perror
开关文件:open/close
读写操作:read/write
定位:lseek
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值