一、文件编程

4.标志IO

7.fwrite

size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
功能:向文件中写入nmemb个大小是size的元素
参数:
    ptr:要写入的元素的首地址
    size:一个元素的字节数
    nmemb:希望写入的元素的个数
    stream:文件流指针
返回值:
    返回实际写入的元素个数

struct stu{
    int id;
    char name[32];
    int score;
};
int main()
{
    FILE*fp = fopen("3.txt","w");
    if(NULL == fp)
    {
        printf("fopen error\n");
        return -1;
    }
    
    //struct stu s = {1,"zhangsan",99};
    //size_t size = fwrite(&s,sizeof(struct stu),1,fp);//传入地址,加&

    struct stu ss[] ={{1,"zhangsan",99},{2,"lisi",78},{3,"wanger",88}};
    size_t size = fwrite(ss,sizeof(struct stu),3,fp);//数组名即为地址
    printf("size = %ld",size);
    fclose(fp);

    return 0;    
}
8.fread
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:从文件中读取nmemb个大小为size的元素
参数:
    ptr:存储读取数据的空间首地址
    size:一个元素的字节数
    nmemb:希望从文件中读到的元素个数
    stream:文件流指针
返回值:
     成功:返回实际读到的元素个数
     失败:0
struct stu{
    int id;
    char name[32];
    int score;
};
int main()
{
    FILE*fp = fopen("3.txt","r");
    if(NULL == fp)
    {
        printf("fopen error\n");
        return -1;
    }
    
    struct stu ss[10];

    size_t size = fread(ss,sizeof(struct stu),10,fp);

    printf("size = %ld\n",size);

    for(int i = 0;i < size;i++)
    {
        printf("%d %s %d\n",ss[i].id,ss[i].name,ss[i].score);
    }

    fclose(fp);

    return 0;
}

注意:

  • fread和fwrite可用来读写字符型文件,也可以用来读写二进制文件

  • fread和fwrite大多数场景用在读写固定大小的数据,如结构体。

9.文件流定位函数
int fseek(FILE *stream, long offset, int whence);
功能:实现文件流中的文件位置定位符的偏移
参数:
     stream:要偏移的文件流
     offset:偏移量
     whence:偏移的起始位置
            SEEK_SET:文件开头   offset > 0
            SEEK_CUR:当前读写位置  offset可正可负
            SEER_END:文件末尾     offset可正可负
返回值:
     成功:0
     失败:-1

long ftell(FILE *stream);
功能:获取当前流所在位置到文件开头的偏移量

void rewind(FILE *stream);
功能:流复位,将流定位到文件开头

获取文件的大小:
fseek(fp, 0, SEEK_END);
len = ftell(fp);
rewind(fp);
int main()
{
    FILE*fp = fopen("4.txt","w");
    if(NULL == fp)
    {
        printf("fopen error\n");
        return -1;
    }

    long offset = 0;

    fseek(fp,5,SEEK_SET);
    fputc('A',fp);
    offset = ftell(fp);
    printf("offset = %ld\n",offset);

    fseek (fp,10,SEEK_CUR);
    fputc('B',fp);
    offset = ftell(fp);
    printf("offset = %ld\n",offset);
    
    fseek(fp,-5,SEEK_CUR);
    fputc('C',fp);

    fseek(fp,5,SEEK_END);
    fputc('D',fp);
    rewind(fp);
    fclose(fp);

    
    return 0;
}

10 其他
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
功能:将格式化后的数据输出到文件
int sprintf(char *str, const char *format, ...);
功能:格式化后的字符串保存在内存

5.文件IO

​ 1. Linux内核向应用层提供的文件操作方法,属于Linux系统调用。

        打开函数 open

        读写函数 read/write

        关闭函数 close

2.函数接口

open
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
功能:打开一个文件
参数:
    pathname:要打开文件的文件名
    flags:打开方式
    	O_RDONLY :只读
    	O_WRONLY :只写
    	O_RDWR  :可读可写
    	O_CREAT :创建
    	O_APPEND :追加
    	O_TRUNC :清空
        "r"    O_RDONLY
        "r+"   O_RDWR
        "w"    O_WRONLY | O_CREAT | O_TRUNC
        "w+"   O_RDWR | O_CREAT | O_TRUNC
        "a"    O_WRONLY | O_CREAT | O_APPEND
        "a+"   O_RDWR | O_CREAT | O_APPEND
    mode :当前用户、同组用户、其他人对文件的读写执行权限
          *当flags标志位中存在O_CREAT方式,则必须增加mode参数
          111 111 111  -----》0777
          mode & ~umask
          注意:创建普通文件时,mode给到0664足够
返回值:
	成功:文件描述符
	失败:-1

​ 文件描述符:

        小的,非负的整形数据,1024个(0-1023)

        操作系统为已打开的文件分配的一个标识符。

        分配原则:最小未被使用原则

        文件IO操作文件面向文件描述符。

操作系统默认已经打开了三个文件:标准输入设备、标准输出设备、标准出错设备

            文件描述符fd      文件流指针FILE*
标准输入设备 ----》0 ---------》stdin
标准输出设备 ----》1 ---------》stdout
标准出错设备 ----》2 ---------》stderr
close
int close(int fd);
功能:关闭文件

注意:对于打开的文件使用完时,要及时关闭。
	 由于文件描述符个数有限,光打开文件不关闭,会造成文件描述符泄露。
write
ssize_t write(int fd, const void *buf, size_t count);
功能:向文件中写入数据
参数:
    fd:要写的文件的文件描述符
    buf:要写入的数据首地址
    count:要写入的字节数
返回值:
	成功:返回实际写入的字节数
	失败:-1
	
read
ssize_t read(int fd, void *buf, size_t count);
功能:从文件中读数据
参数:	
	fd:文件描述符
	buf:存储数据的空间首地址
	count:期望读到的字节数
返回值:
	成功:返回实际读到的字节数
	失败:-1
	到达文件末尾:0

练习:使用文件io实现cat功能

char *strtok(char *str, const char *delim);
功能:字符串分割
参数:
	str:要分割字符串的首地址
	delim:分隔符
返回值:
	成功:返回分隔到的字符串的首地址
	失败:NULL
*使用文件IO实现文件的拷贝
int copy_file(const char *srcname, const char *dstname)
{
	int fdsrc = open(srcname, O_RDONLY);
	int fddst = open(dstname, O_WRONLY | O_CREAT | O_TRUNC, 0664);
	if (fdsrc < 0 || fddst < 0)
	{
		printf("open error\n");
		return -1;
	}
	char buff[1024] = {0};
	while (1)
	{
		ssize_t size = read(fdsrc, buff, sizeof(buff));
		if (size <= 0)  //==0 :文件末尾  <0 :出错
		{
			break;
		}
		write(fddst, buff, size);
	}
	close(fdsrc);
	close(fddst);

	return 0;
}

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐