Linux文件IO函数与标准IO库函数

Linux中,文件有为操作系统和设备提供了一个简单而统一的接口。在Linux中,几乎一切都可以看做文件 。
Linux对文件的操作有两种方式文件IO函数(系统调用)和标准IO库函数调用。系统调用是最直接的方式,库函数调用最终也是通过系统调用实现的。可认为库函数调用是对系统调出于效率考虑而做出的优化。
二者区别:
系统调用是操作系统相关的,因此一般没有跨操作系统的可移植性。
库函数调用是系统无关的,因此可移植性好。标准的IO库函数对文件的操作最终是通过系统调用实现的,但标准io函数库采用缓存技术,减少系统调用的次数。
系统调用通常用于底层文件访问(low-level file access),例如在驱动程序中对设备文件的直接访问。
库函数调用通常用于应用程序中对一般文件的访问。
一、文件IO函数–系统调用
基本函数:

#include<unistd.h>
int open(const char *path, int flags);
-->打开或创建一个文件
int open(const char *path, int flags, mode_t mode );
-->当用于创建文件时需要用第二个函数指明文件的相关权限信息
size_t write(int fd, const void *buf, size_t nbytes);
-->
size_t read(int fd, void *buf, size_t nbytes);
int close(int fd);
off_t lseek(int filedes, off_t offset, int whence);
-->设置读写文件的当前位置
whence有三个参数SEEK_SET/SEEK_CUR/SEEK_END(文件开始/当前/结束位置),则文件的偏移量为设置的whence参数加上offset

二、标准IO库函数

    在基于文件描述符中的底层系统调用的I/O操作中,所有的I/O函数都是针对文件描述符的。当打开一个文件时,即返回一个文件描述符,然后该问价描述符就用于后续的I/O操作。
    在标准I/O库中,所有的I/O操作都是围绕流(stream)来进行的。在Linux中,文件和设备都可以看做是数据流。 
    Linux对一个进程预定义了三个流:标准输入流,标准输出流和标准错误输出流,它们自动地为进程打开并可用。这三个标准I/O流通过在头文件<stdio.h>中预定义的文件指针stdin,stdout和stderr加以引用。它们与文件描述符STDIN_FILENO,STDOUT_FILENO和STDERR_FILENO所表示的标准输入,标准输出和标准错误输出相对应。
     标准I/O库提供了函数fopen用于打开一个流。当打开一个流时,该函数会返回一个指向FILE对象的指针,即文件指针(类型为FILE *)。FILE对象通常是一个结构,它包含了I/O库为管理该流所需要的所有信息:用于实际I/O的文件描述符,指向流缓存的指针,缓存长度,当前在缓存中的字节数,出错标志等。但一般应用程序没有必要关心FILE结构体的各成员值,使用流时,只需要将FILE指针作为参数传递给每个标准I/O函数。 

基本函数:

#include <stdio.h>
FILE *fopen(const char *path, const char *mode);
FILE *fdopen(int fd, const char *mode);-->使一个标准的I/O流与该描述相结合。
FILE *freopen(const char *path, const char *mode, FILE *stream);
-->在指定的流上打开一个指定的文件,此函数一般用于将一个指定的文件打开为预定义的流(如标准输出)。
int flose(FILE *fp);-->关闭流

读写流:
(1)每次一个字符的IO

int getc(FILE *fp);
int fgetc(FILE *fp);
int getchar(void);
/* 上面三个函数的返回值为int,因为EOF常实现为-1,返回int就能与之比较 */

/* 判断出错或者结束 */
int ferror(FILE *fp);
int feof(FILE *fp);
void clearerr(FILE *fp); /* 清除error或者eof标志 */

/* 把字符压送回流 */
int ungetc(intc FILE *fp);

/* 输出 */
int putc(int c, FILE *fp);
int fputc(int c, FILE *fp);
int putchar(int c);

(2)每次一行的IO。

#include <stdio.h>
/* 输入 */
char *fgets(char *restrict buf, int n, FILE *restrict fp);
char *gets(char *buf);
/* gets由于没有指定缓冲区,所以有可能造成缓冲区溢出,要小心 */

/* 输出 */
int fputs(char *restrict buf, FILE *restrict fp);
int puts(const char *buf);

(3)直接IO

#include <stdio.h>
size_t fread(void *restrict ptr, size_t size, size_t nobj,
            FILE *restrict fp);
size_t fwrite(const void *restrict ptr, size_t size, size_t nobj,
            FILE *restrict fp);
/* 返回值:读或写的对象数 */

定位流

long ftell(FILE *fp);
/* 成功则返回当前文件位置指示,出错返回-1L */

int fseek(FILE *fp, long offset, int whence);
/* 成功返回0, 出错返回非0 */

int fgetpos(FILE *restrict fp, fpos_t *restrict pos);
int fsetpos(FILE *fp, fpos_t *pos);
/* 成功返回0,出错返回非0 */

格式化IO

执行格式化输出的主要是4printf 函数:
    printf  输出到标准输出
    fprintf  输出到指定流
    sprintf  输出到指定数组
    snprintf  输出到指定数组并在数组的尾端自动添加一个null字节
格式化输入主要是三个 scanf 函数:
    scanf  从标准输入获取
    fscanf  从指定流获取
    sscanf  从指定数组获取

猜你喜欢

转载自blog.csdn.net/Gouhailiang/article/details/73123974