Linux C高级编程——文件操作之库函数

Linux C高级编程——文件操作库函数


宗旨:技术的学习是有限的,分享的精神是无限的


——为什么要设计标准I/O库?

直接使用API进行文件访问时,需要考虑许多细节问题

例如:read、write时,缓冲区的大小该如何确定,才能使效率最优

标准I/O库封装了诸多细节问题,包括缓冲区分配

 

——标准I/O库缓冲

标准I/O库提供缓冲的目的:尽可能减少使用read、write调用的次数,以提高I/O效率。

通过标准I/O库进行的读写操作,数据都会被放置在标准I/O库缓冲中中转。

 

——缓冲类型

—全缓冲

在填满标准I/O缓冲区后,才进行实际I/O操作(例如调用write函数)

调用fflush函数也能强制进行实际I/O操作

—行缓冲

在输入和输出遇到换行符时,标准I/O库执行I/O操作

因为标准I/O库用来收集每一行的缓存的长度是固定的,所以,只要填满了缓存,即使没有遇到新行符,也进行I/O操作

终端(例如标准输入和标准输出),使用行缓冲

—不带缓冲

标准I/O库不对字符进行缓冲存储

标准出错是不带缓冲的,为了让出错信息尽快显示出来

 

——流的定向

对于ASCII字符集,一个字符用一个字节表示

对于国际字符集,一个字符可用多个字节表示

流的定向决定了所读、写的字符是单字节还是多字节的 

 

一、打开关闭文件

1fopen

——用于打开一个指定的文件

(1)函数原型

#include<stdio.h>
FILE* fopen(const char *restrict pathname, const char *restrict type);

(2)参数

        pathname:要打开的文件名

        type:指定文件的读、写方式

r/rb——只读方式打开

w/wb——只写,不存在则创建,使文件长度为0

a/ab——追加

r+/r+b/rb+——读写打开

W+/w+b/wb+——使文件长度为0,读写而打开

a+/a+b/ab+——在文件尾读和写而打开或创建

(3)返回值

        ——FILE结构指针(open返回的是文件描述符)

 

2fflush

——刷新一个流(强制标准I/O库进行系统调用,以将数据传递到内核)

(1)函数原型

int fflush(FILE *fp);

(2)函数参数

        fp:文件指针;若fp=NULL,则刷新所有输出流

(3)返回值

        成功返回0,出错返回EOF

 

3fclose

——关闭一个打开了的流

(1)函数原型

 int fclose(FILE *fp);

(2)函数参数和返回值

          fp:要关闭的流对应的文件指针

(3)返回值

         —成功返回0,出错返回EOF

         在该文件被关闭之前,刷新缓存中的输出数据。缓存中的输入数据被丢弃,如果标准I/O库已经为该流自动分配了一个缓存,则释放此缓存。

 

二、读写文件流

1、字符读/写文件流

1.1fgetc

——读出流中的一个字符

(1)函数原型

int  fgetc(FILE *fp);

(2)函数参数

        fp:文件指针

(3)返回值

        成功返回读到的内容; 出错返回-1。


1.2fputc

——写一个字符到文件流中

(1)函数原型

int  fputc(int c, FILE *fp);

(2)函数参数

        c:字符c

        fp:文件指针

(3)返回值

        成功返回内容; 出错返回-1


2、行读写文件流(一行一行进行)——不能操作二进制文件

2.1fgets

——读出流中的一行字符串

(1)函数原型

char *fgets(char *s, int n, FILE *fp);

(2)函数参数

         s:字符串指针,指向用来存储所得数据的地址

         n:缓冲区大小

        fp:文件指针

(3)返回值

        成功返回读到的内容到s中; 出错返回NULL。


2.2fputs

——写一行字符串到标准流中

(1)函数原型

int *fputs(char*s, FILE *fp);

(2)函数参数

        s:以空字符结尾的字符串(后接换行符)写入标准流stdout中

        fp:文件指针

(3)返回值

        成功返回非负数; 出错返回-1。


3、块读写文件流 (fread/fwrite)

——每次I/O操作读写某种数量的对象,而每个对象具有指定的长度

例如,可读写一个二进制数组、结构

(1)函数原型

size_t fread(void *ptr, size_t size, size_t nobj, FILE *fp);
size_t fwrite(const void *ptr, size_t size, size_t nobj, FILE *fp);

(2)参数

        第一个参数ptr:用于读写的缓冲区

        第二个参数size:每个对象的大小

        第三个参数nobj:要读写的对象个数

        第四个参数fp:文件指针

(3)返回值

        返回实际读/写的对象数


三、文件流定位

1、ftell

——用于获取当前文件偏移量

(1)函数原型

long ftell(FILE *fp);

(2)函数参数

         fp:文件指针

(3)返回值

        成功返回当前文件偏移量; 出错返回-1。

 

2、fseek

——用于设置当前文件偏移量

(1)函数原型:

int fseek(FILE *fp, long offset, int whence);

(2)函数参数

        第一个参数fp:文件指针

        第二个参数offset:相对偏移量:需结合whence才能计算出真正的偏移量

        第三个参数whence:该参数取值是三个常量

SEEK_SET: 当前文件偏移量为:距文件开始处的offset个字节  

SEEK_CUR: 当前文件偏移量为:当前文件偏移量+offset(可正可负)                       

SEEK_END: 当前文件偏移量为:当前文件长度+offset(可正可负)  

(3)返回值

        成功返回0,出错返回非0     

                         

3、rewind                                  

—— 用于将文件偏移量设置到文件的起始位置    

(1)函数原型

void rewind(FILE *fp);

(2)函数参数

        fp:文件指针 

(3)返回值

// 小程序:用标准库函数实现文件拷贝功能:
#include<stdio.h>
//#include<string.h>
#include<stdlib.h>

void file_copy(char *fd, char *fp);

int main(intargc, char **argv)
{
  file_copy(argv[1], argv[2]);

  return 0;
}

void file_copy(char *fd, char *fp)
{
  FILE *from_fd, *to_fd;
  int ret, file_len; //定义文件大小
  char buffer[1024];//缓冲区

  if((from_fd = fopen(fd, "rb")) == NULL) //打开目标文件
  {
    printf("file openfail!\n");
    exit(1);
  }
  if((to_fd = fopen(fp, "wb")) == NULL) //创建新文件
  {
    printf("file openfail!\n");
    exit(0);
  }
  fseek(from_fd, 0L, SEEK_END);
  file_len = ftell(from_fd);//计算文件大小
  fseek(from_fd, 0L, SEEK_SET);

  if((ret = fread(buffer, file_len, 1, from_fd)) == -1) //读取文件到buffer中,返回实际读到的对象个数(不是读取的字节数)
  {
    printf("file readfail!\n");
    exit(0);
  }
  //printf("!!!!!!!!!!!%d\n",ret);

  fwrite(buffer, file_len, 1, to_fd); //把buffer里面的内容写到新文件中

  fclose(from_fd);
  fclose(to_fd);//关闭文件
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值