Linux 05 标准IO及相关函数

  用户在应用开发过程中会经常需要访问文件。Linux下读写文件的方式有两大类:标准IO和文件IO。其中标准IO是最常用,也是最基本的内容,可以说标准IO是文件IO的再封装。

一、标准IO

文件类型
​	普通文件 -
​	目录文件 d
​	管道文件 p
​	链接文件 l
​	字符设备文件 c
​	块设备文件 b
​	套接字文件 s

注意: 不同操作系统适用的文件类型不同

1. 标准IO

标准IO遵循ANSI C标准,标准IO实际是调用标准C库中的函数

特点:
	标准IO利用缓冲机制,减少系统调用的次数,从而提高程序运行的效率。

标准IO - 高级IO
文件IO - 低级IO
标准IO是在文件IO的基础上做的一次再封装
标准IO一般用于操作普通文件
2. 流

数据仅是简单地从文件进行流入、流出,称这种现象为流。

流在文件中用FILE结构体描述。

/* FILE结构体的部分定义 */
struct _IO_FILE
{
	char *_IO_buf_base;   /* Start of reserve area. 缓冲区起始位置*/
 	char *_IO_buf_end;    /* End of reserve area. */
	int _fileno;		  /* 文件描述符 */
	......
}

//在一个程序中,一个FILE结构体对应一个文件
3. 流的类型

流的类型有两种:文本流、二进制流

1)文本流

将数据转换为对应的ASCII码再进行存取

2)二进制流

将数据转换为二进制再进行存取

文本流和二进制流处理换行符方式不同:

在linux中,没有对文本流和二进制流做区分,换行符不做任何处理。

文本流:

  将换行符转换为 ‘\r’‘\n’

二进制流:

  换行符不做处理 ‘\n’

4. 缓冲区类型

1)全缓冲

打开一个文件时,默认使用全缓冲。

当缓冲区满或者空时,才进行实际的IO操作

2)行缓冲

当输入输出跟终端相关时,使用行缓冲。

当缓冲区满或者遇到换行符时才进行实际的IO操作

3)无缓冲

跟错误输出相关时使用无缓冲

三个特殊流(默认打开):
	标准输入流 - stdin	- 键盘
	标准输出流 - stdout  - 终端
	标准错误流 - stderr

三、标准IO相关库函数

fopen()/fclose()	打开/关闭文件
fgetc()/fputc()		按字节读/写文件
fgets()/fputs()		按行读/写文件
fread()/fwrite()	按对象(固定大小)/写文件
ftell()/fseek()/rewind()	定位文件(文件指针位置)
fflush()			刷新流(强制刷新缓冲区)
feof()				判断错误流
1) 打开文件 fopen()

FILE *fp = fopen("1.c","r");

#include <stdio.h>
FILE *fopen(const char *pathname, const char *mode);
返回值:
	成功返回对应的文件的流指针,失败返回NULL,并设置错误号(errno)
    errno: 当前系统中最后一个错误的编号
------------------------------------------------------------
    #include <string.h>
    char *strerror(int errnum);
	参数 errnum 错误号
    返回值	成功返回错误原因
------------------------------------------------------------
    #include <stdio.h>
    void perror(const char *s);
------------------------------------------------------------    
参数:
	pathname:	打开文件的文件名(包含路径)
    mode    :	打开文件的方式
        r   以只读方式打开文件,文件必须要存在
        r+  以读写方式打开文件,文件必须要存在
		w	以只写方式打开文件,文件不存在则先创建再打开
        w+	以读写方式打开文件,文件不存在则先创建再打开
        a	以只写[追加]方式打开文件,文件不存在则先创建再打开
        a+	以读写[追加]方式打开文件,文件不存在则先创建再打开
2) 关闭文件 fclose()

fclose(fp);

#include <stdio.h>
int fclose(FILE *stream);
参数:
	stream: 关闭文件对应的流指针
返回值:
	成功返回0, 失败返回 -1;
3) 按字节读/写文件 fgetc()/fputc()
FILE *fp = fopen("1.txt","r");
if(NULL == fp){
    perror("open 1.txt");
    return -1;
}
char c = fgetc(fp);
fputc(c,fp);
fclose(fp);
#include <stdio.h>
int fgetc(FILE *stream);
参数:
	stream: 流指针
返回值:
	成功返回读取的字符, 失败返回 -1;
	读到文件末尾返回 -1;
#include <stdio.h>
int fputc(int c,FILE *stream);
参数:
	c:	输入的字符
	stream: 流指针
返回值:
	成功返回写入的字符, 失败返回 -1;
/*
练习:
	用fgetc()和fputc()完成文件的复制
	终端输入命令:
		./a.out src.txt dest.txt
*/
#include <stdio.h>
int main(int argc,char *argv[])
{
    if(argc != 3){
        printf("Usage:%s <src filename> <dest filename>\n",argv[0]);
        return -1;
    }

    FILE *fp1 = fopen(argv[1],"r");
    if(NULL == fp1){
        perror(argv[1]);
        return -1;
    }
    FILE *fp2 = fopen(argv[2],"a+");
    if(NULL == fp2){
        perror(argv[2]);
        return -1;
    }

    char c;
    while((c = fgetc(fp1)) != EOF){
        fputc(c,fp2);
    }

    fclose(fp1);
    fclose(fp2);

    return 0;
}
4) 按行读写 fgets()/fputs()
#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
参数:
	s:	 	字符串首地址
    size:	请求读取数据的最大长度
    stream: 流指针
返回值:
	成功返回得到字符串的首地址, 失败返回NULL;
注意:① 当读取内容为换行符,读取结束
	 ② 最大读取内容为 size-1; 因为size位置要为'\0' 
#include <stdio.h>
char *fputs(char *s,FILE *stream);
5) 按对象读写 fread()/fwrite()
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
返回值:
	成功返回读到的对象个数, 失败返回 0;
参数:
	ptr:	存放字符串的首地址
    size:	对象大小
	nmemb:	对象个数
	stream:	流指针
#include <stdio.h>
size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream);
返回值:
	成功返回写入的对象个数, 失败返回 0;
参数:
	ptr:	存放字符串的首地址
    size:	对象大小
	nmemb:	对象个数
	stream:	流指针
//上文中 用fgetc()/fputc() 复制文件的改写
int ret;
char buf[64] = {0};
while((ret = fread(buf, sizeof(char), 1, fp1)) != 0){
    fwrite(buf,sizeof(char),1,fp2);
}
6) 刷新流 fflush()
#include <stdio.h>
int fflush(FILE *stream);
参数:
	stream:	流指针
返回值:
	成功返回 0,失败返回 -1;
7) 定位文件 ftell() / fseek() / rewind()
#include <stdio.h>

long ftell(FILE *stream);
功能:
	返回文件指针相对于文件开头的偏移量
参数:
	stream:	流指针
返回值:
	成功返回文件指针相对于文件开头的偏移量,失败返回 -1;
int fseek(FILE *stream, long offset, int whence);
功能:
	将文件指针定位到offset+whence位置
参数:
	stream:	流指针
    offset:	偏移量(可正可负)
	whence:	基准点
		SEEK_SET:	将文件指针定位在文件开头
        SEEK_CUR	将文件指针定位在当前位置
		SEEK_END	将文件指针定位在文件末尾
返回值:
	成功返回0, 失败返回 -1;
void rewind(FILE *stream);
功能:
	将文件指针定位到文件开头
8) 判断错误流 feof()
#include <stdio.h>
int feof(FILE *stream);
返回值:
	1	表示流访问结束
    0	表示错误返回
9) fprintf() / sprintf()
#include <stdio.h>
//格式化输出到流
int fprintf(FILE *stream,const char *format,...);

//格式化输出到str指向的字符串
int sprintf(char *str,const char *format,...);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值