《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 .

 

發佈了34 篇原創文章 · 獲贊 17 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章