系统io(文件io)

文件I/O

文件描述符:

文件描述符:已打开文件的标志,是非负整形数,当前可以最小作为新文件的文件描述符,默认范围0-1024(可更改)。

文件打开:

int open(const char *pathname, int flags, mode_t mode);
    1. pathname:要打开文件的路径
    2. flags:打开方式
        1.O_RDONLY    只读
        2.O_WRONLY    只写
        3.O_RDWR      读写
        **上述常量三选一**
        **下列可选择的:**
        O_APPEND  每次写时追加到文件尾端。
        O_TRUNC    如果文件存在将其截短为0。
        O_CREAT     创建文件,使用此时,指定文件权限位。 文件权限位 & ~umask(屏蔽字).
    3.mode:mode & ~umask创建文件的权限
    4. 返回值:成功返回文件描述符,失败返回-1 并且设置 errno

读:

ssize_t read(int fd, void *buf, size_t count);
    1. fd:待读取的文件的文件描述符
    2. buf:存储读取到的数据
    3. count:buf大小
    4. 返回值:成功返回读到的字节个数,失败返回-1,读到结尾返回 0 .

写:

ssize_t write(int fd, const void *buf, size_t count);
    1. fd:要写入的文件的文件描述符
    2. buf:存储待写入的数据
    3. count:待写入的字节个数
    4. 返回值:成功返回写入的字节个数,失败返回-1.

设置文件偏移量:

off_t lseek(int fd, off_t offset, int whence);
    1. fd:要写入的文件的文件描述符
    2. offset:要偏移的字节个数
    3. whence:设置从何处开始偏移
        1. SEEK_SET   文件开头
        2. SEEK_CUR   从当前位置
        3. SEEK_END   文件末尾
    4. 返回值:成功返回当前文件偏移量,若出错返回-1.

关闭:

int close(int fd);

文件共享:

1. 进程表项:每一个进程有一个
2. 文件表:每打开一个文件
3. v结点表:一个文件一个

文件共享

文件描述符的复制--》重定向:

1. int dup(int oldfiledes)//标识符,当前可用最小文件描述符最为oldfd的赋值
返回值:返回当前可用文件描述符中的最小数值,出错返回-1.

2. int dup2(int oldfd, int newfd);//如果newfd被占用了,先关掉,让newfd作为oldfd的赋值。dup2能够指定fd给oldfd赋值

返回值:成功返回文件新的描述符,出错返回-1.
3. ./a.out > outfile 2>&1
    dup2(fd, 1);
    dup2(1, 2);
4. ./a.out 2>&1 > outfile
    dup2(1, 2);
    dup2(fd, 1);

fcntl(2):

int fcntl(int fd, int cmd, /* int arg */)文件描述符, 功能描述符, 第三个参数是一个整数,指向结构体的指针。

fcntl函数的5种功能:
    1.复制一个现有的描述符。(cmd = F_DUPFD)(很少用)
    2.获得/设置文件描述标记。(cmd = F_GETFD / F_SETFD)
    3.获得/设置文件状态标志。(cmd = F_GETFL / F_SETFL)
    4.获得/设置异步i/o所有权  (cmd = F_GETOWN/F_SETOWN)
    5.获得/设置记录锁   (cmd = F_GETLK/cmd = F_SETLK/  cmd = F_SETLKW)

标准io

1. 文件流:FILE结构:fd,buf,bufsize,errflag;标准io打开文件的标记
2. 标准输入文件流stdin  标准输出文件流stdout 标准错误输出stderr
3. 缓存
    1. 行缓存stdout/stdin
    2. 无缓存stderr
    3. 全缓存 (普通文件)
4. 如何刷新缓存区
    1. 行缓冲遇到'\n'
    2. 全缓存写满了
    3. 进程终止了
    4. fflush(3) //强制刷新缓存
5. 打开
    1. FILE *fopen(const char *path, const char *flag);//1.文件打开路径,2.以哪种方式打开文件
        返回值文件流
        1. flag:r/r+/w/w+/a/a+
                r:	读
		r+	可读可写
		w	把文件截短为0,或为写而创建。
		w+	把文件截短为0,或为读和写而打开
		a	添加,在文件末尾写而打开。或为写而创建
		a+	为在文件末尾写而打开或创建
6. 读写
    1. 字节
        1. fgetc(3) / fputc(3) getc(3) / putc(3) getchar(3)/putchar(3)

        fgetc(3):int fgetc(int c,FILE* fp)参数:FILE* 指针
		功能:读取一个字符
		返回值:成功返回下一个字符,若读到文件末尾或失败则返回EOF,(此时需要判断读到文件末尾还是读取失败)(调用ferror或feof)
 	fputc(3): int fputc(int c, FILE * STREAM)//int c 转换成无符号字符,写进要写进的文件流中
		将指定输出项 输出到一个指定流上,包括标准输出流,标准出错流,以及任何一个已经成功打开的流(文件),将转换为无符号字符的字符C写入流


	getc(3) :
		从任何成功打开的流中获取内容,包括标准输入以及已经存在的文件中。getc()会被定义成宏使用
	putc(3) :int putc(int c,FILE * STREAM)//int c 转换成无符号字符,写进要写进的文件流中
		将指定输出项 输出到一个指定流上,包括标准输出流,以及任何一个已经成功打开的流(文件),它可以作为一个宏来实现
	getchar(3):int getchar(void);
		从标准输入读入一个字符(函数参数是标准输入,即终端)


	putchar(3):
		把指定的字符输出到标准输出(即终端)

    2. 行
        1. fgets(3) / fputs(3)  puts(3)

        fgets(3) : char *fgets(char *buf, int size, FILE *fp);//从后往前:从文件流中读,读多少字节,读到缓存中去。
		返回值:成功返回s,已达到文件末尾或失败则返回NULL。
	fputs(3):  int fputs(const char *s, FILE *stream);//只读的缓冲区,文件流
		返回值:成功返回非负数,失败返回eof
	puts(3):int puts(const char *s);//指针所指向的内容
		返回值:成功返回非负数,失败返回eof

    3. 二进制
        1. int fread(char *buf, int size, int nmemb, FILE *fp);//要读到的地方,单个元素大小,多少个元素,从文件流中读
        
        2. int fwrite(const char *buf, int size, int nmemb, FILE *fp);//从缓存中读,单个元素大小,多少个元素,写入文件流中

        如果成功,fread()和fwrite()将返回读或写的项目数量。这个数字等于仅在size为1时传输的字节数。如果一个错误oc‐curs,或到达文件的结尾,返回值是一个短的项目计数(或0)。
        fread()不区分文件结束符和错误,调用者必须使用feof(3)和ferror(3)来确定发生了什么。

    4. 格式化
        1. printf(3) / scanf(3)
        2. fprintf(3) / snprintf(3)
7. 关闭
    1. fclose(3)
8. 偏移量(定位文件流位置)
    1.fseek(3) / ftell(3)(获得文件偏移量)/rewind(3)(文件偏移量回到文件开头)
      int fseek(FILE *stream, long offset, int whence); 返回值:成功返回0,失败返回非0值。
      long ftell(FILE *stream);获得文件偏移量。
      void rewind(FILE *stream);功能:将当前文件的偏移量置为0
9. 临时文件
    1. tmpfile(3)  //成功返回文件指针,失败返回NULL

文件io和标准io区别与联系

文件io:

  系统调用
  实时性高
  效率低
  不能跨平台

标准io:

  库函数
  带缓存区
  合并系统调用,减少io次数,提高效率,能合并系统调用是因为它带缓存区
  实时性低

posted @ 2021-03-16 22:49  小浩small  阅读(291)  评论(0)    收藏  举报