《libc 中的文件IO函数》

1. 文件描述符与文件指针

文件描述符:在linux系统中打开文件就会获得文件描述符,它是个很小的正整数。每个进程在PCB(Process Control Block)中保存着一份文件描述符表,文件描述符就是这个表的索引,每个表项都有一个指向已打开文件的指针。套接字和管道都是文件描述符

文件指针:C标准库中使用文件指针做为文件I/O的句柄。文件指针指向进程用户区中的一个被称为FILE结构的数据结构。FILE结构包括一个缓冲区和一 个文件描述符。而文件描述符是文件描述符表的一个索引,因此从某种意义上说文件指针就是句柄的句柄(在Windows系统上,文件描述符被称作文件句 柄)。stderr、stdout、stdin都是文件指针

2. 基于文件描述符的I/O函数

基于文件描述符的I/O函数有:open, close, read, write, getc, getchar, putc, putchar等。他们属于系统调用,更接近于硬件,属于非缓冲文件系统的IO函数。

非缓冲文件系统依赖于操作系统,通过操作系统的功能对文件进行读写,是系统级的输入输出,它不设文件结构体指针,只能读写二进制文件(对于UNIX系统内核而言,文本文件和二进制代码文件并无区别),但效率高、速度快。由于ANSI标准不再包括非缓冲文件系统,因此,在读取正规的文件时,建议大家最好不要选择它。

1)open/close:open打开文件,返回一个文件描述符;close关闭打开的文件。

       #include <sys/types.h>
       #include <sys/stat.h>
       #include <fcntl.h>

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

       #include <unistd.h>

       int close(int fd);

2)read/write:文件的读写操作,向给定的文件描述符读取或者写入数据块,操作的都是二进制数据。

       #include <unistd.h>

       ssize_t read(int fd, void *buf, size_t count);

       #include <unistd.h>

       ssize_t write(int fd, const void *buf, size_t count);

3. 基于文件指针的I/O函数

基于文件指针的I/O函数有:fopen,fclose,fread,fwrite,fgetc,fgets,fputc,fputs,freopen,fseek,ftell,rewind, fprintf等。他们属于库函数,是对open,write等系统调用的封装,属于缓冲文件系统的I/O函数。

缓冲文件系统是借助于文件结构体指针FILE *来对文件进行管理,通过文件指针对文件进行访问,即可以读写字符、字符串、格式化数据,也可以读写二进制数据。

1)fopen/fclose:打开或关闭文件。

       #include <stdio.h>

       FILE *fopen(const char *path, const char *mode);
       FILE *fdopen(int fildes, const char *mode);
       FILE *freopen(const char *path, const char *mode, FILE *stream);

       #include <stdio.h>

       int fclose(FILE *fp);

2)fread/fwrite/fgetc/fgets/fputc/fputs:通过文件指针读写文件。

       #include <stdio.h>

       size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

       size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

       #include <stdio.h>

       int fgetc(FILE *stream);
       char *fgets(char *s, int size, FILE *stream);
       int getc(FILE *stream);
       int getchar(void);
       char *gets(char *s);
       int ungetc(int c, FILE *stream);

       #include <stdio.h>

       int fputc(int c, FILE *stream);
       int fputs(const char *s, FILE *stream);
       int putc(int c, FILE *stream);
       int putchar(int c);
       int puts(const char *s);

3)fseek/ftell/rewind:获取或者重置文件操作位置。

       #include <stdio.h>

       int fseek(FILE *stream, long offset, int whence);
       long ftell(FILE *stream);
       void rewind(FILE *stream);
       int fgetpos(FILE *stream, fpos_t *pos);
       int fsetpos(FILE *stream, fpos_t *pos);

 4)fprintf/sprintf/snprintf:格式化输出函数

       #include <stdio.h>

       int printf(const char *format, ...);
       int fprintf(FILE *stream, const char *format, ...);
       int sprintf(char *str, const char *format, ...);
       int snprintf(char *str, size_t size, const char *format, ...);

5)scanf/fscanf/sscanf:格式化输入函数

       #include <stdio.h>
       int scanf(const char *format, ...);
       int fscanf(FILE *stream, const char *format, ...);
       int sscanf(const char *str, const char *format, ...);

 

PS: 用freadfwrite,它自动分配缓存,速度会很快,比自己来做要简单。如果要处理一些特殊的描述符,readwrite,如套接口,管道之类的。

 

实例:

[root@HPC-NQS file_io]# cat file_read.c

#include <stdio.h>

#define MAX_LINE 1024

int main (int argc, char* argv[])
{
    FILE *fp;
    char s[MAX_LINE];

    fp=fopen(argv[1],"r");

    printf("current position:%ld .\n",ftell(fp));

    printf("first line is:%s\n",fgets(s,MAX_LINE,fp));
    printf("current position:%ld .\n",ftell(fp));

    printf("some character folow:\n%c%c%c\n",fgetc(fp),fgetc(fp),fgetc(fp));
    printf("current position:%ld .\n",ftell(fp));

    rewind(fp);
    printf("position after rewind:%ld .\n",ftell(fp));

    fseek(fp,0,SEEK_END);
    printf("position after fseek(fp,0,SEEK_END):%ld .\n",ftell(fp));

    return 0;
}


输出结果:

[root@HPC-NQS file_io]# ./file_read file_read.c
current position:0 .
first line is:#include <stdio.h>

current position:19 .
some character folow:
d#

current position:22 .
position after rewind:0 .
position after fseek(fp,0,SEEK_END):613 .

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值