【C语言】文件操作全解速览

简介: 【C语言】文件操作全解速览

文件操作

  文件分为二进制文件和文本文件,文本文件里面保存的内容形式是ASCII字符,二进制文件里面内容保存形式是01表示的。文件的主要作用是用来进行数据的持久化,能去长久的保存数据。这里f开头的文件操作命令,大多是c标准库里面的文件操作命令。

  每个进程的PCB里面都有一份文件描述符表,文件描述符就是这个表的索引,通过索引可以获取这个文件描述符表中的内容,这个内容就是指向打开文件的FILE结构体指针。不同操作系统定义的FILE结构体不太一样,这里我拿出我的这一种作为参考。

struct _IO_FILE {
   
  int _flags;        /* High-order word is _IO_MAGIC; rest is flags. */
#define _IO_file_flags _flags

  /* The following pointers correspond to the C++ streambuf protocol. */
  /* Note:  Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
  char* _IO_read_ptr;    /* Current read pointer */
  char* _IO_read_end;    /* End of get area. */
  char* _IO_read_base;    /* Start of putback+get area. */
  char* _IO_write_base;    /* Start of put area. */
  char* _IO_write_ptr;    /* Current put pointer. */
  char* _IO_write_end;    /* End of put area. */
  char* _IO_buf_base;    /* Start of reserve area. */
  char* _IO_buf_end;    /* End of reserve area. */
  /* The following fields are used to support backing up and undo. */
  char *_IO_save_base; /* Pointer to start of non-current get area. */
  char *_IO_backup_base;  /* Pointer to first valid character of backup area */
  char *_IO_save_end; /* Pointer to end of non-current get area. */

  struct _IO_marker *_markers;

  struct _IO_FILE *_chain;

  int _fileno;        //文件描述符
};
typedef struct _IO_FILE FILE;

1. 文件的打开和关闭

  要对文件操作,首先要打开文件,打开文件使用fopen函数,返回的是一个FILE类型指针。这个FILE指针指向的是一个文件节点,里面有文件操作的基本信息。

fopen()/fclose()

文件的打开和关闭

#include <stdio.h>
//filepath 文件路径,mode打开模式
FILE * fopen(const char * filepath, const char * mode);

#include <stdio.h>
//关闭文件
int fclose(FILE * fp);


//mode ,其中b是二进制文件
//r或rb只读模式
//w或wb写模式(文件有内容就清空),文件不存在就新建
//a或ab追加模式,在文件末尾添加内容,文件不存在就创建
//r+或者rb+以可读可写方式打开文件
//w+或者wb+以可读可写方式打开文件,没有就新建
//a+或者ab+以追加可读可写方式打开文件,没有就创建

//案例
FILE *file = fopen("hello.txt", "w+");
if(file==NULL)
{
   
    perror("open");
    return -1;
}
fclose(file);

2. 文件读写位置相关

EOF表示文本文件结束符,在读取文件时作为读取文件结束标志。

#define EOF (-1)

feof()

判断是否读取到了文件结尾

#include <stdio.h>
int feof(FILE * stream);
//返回 
//非0:已经到文件结尾
//0:没有到文件尾

ftell()

获取文件流的读写位置

#include <stdio.h>
long ftell(FILE *stream);

fseek()

移动文件的读写位置

#include <stdio.h>
//fp是打开的文件指针
//offset是偏移量,正数是基于whence向后偏移,负数是基于whence向前偏移
//whence选取:
//SEEK_SET:文件开头
//SEEK_CUR:当前位置
//SEEK_END:文件末尾
int fseek(FILE *fp, long offset, int whence);


//案例 利用函数获取文件大小
fseek(fp,0,SEEK_END);
int len=ftell(fp);
printf("size is %d\n",len);

rewind()

把文件流的读写位置移动到文件开头

#include <stdio.h>
void rewind(FILE *stream);

3. 文件内容读取

fgetc()/fputc()

按照字符读取文件

#include <stdio.h>
//获取 fp 中的字符数据
int fgetc(FILE *fp);
//将ch转换为unsigned char后写入 fp 指定的文件中
int fputc(int ch, FILE * fp);


//案例 拷贝一个文件
FILE *file = fopen("hello.txt", "a+");
FILE *new = fopen("new.txt", "a+");
char ch;
while(!feof(file))
{
   
    ch = fgetc(file);
    fputc(ch,new);
    printf("%c",ch);
}
fclose(file);
fclose(new);

fgets()/fputs()

按照行读取文件

#include <stdio.h>
//从 filepath 读入字符,保存到str,直到出现换行字符、读到文件结尾或是已读了size - 1个字符为止,最后会自动加上字符 '\0' 作为字符串结束。
char * fgets(char * str, int size, FILE * filepath);
//将str写入 filepath 中,字符串结束符 '\0'  不写入文件
int fputs(const char * str, FILE * filepath);

//案例 拷贝一个文件
FILE *file = fopen("hello.txt", "r+");
FILE *new = fopen("new.txt", "w+");
char buf[100] = {
   0};

while (!feof(file))
{
   
    memset(buf, 0, sizeof(buf));
    char *p = fgets(buf, sizeof(buf), file);
    if (p != NULL)
    {
   
        fputs(buf,new);
        printf("%s", buf);
    }
}
fclose(file);
fclose(new);

fprintf()/fscanf()

按照格式读写文件。

#include <stdio.h>
//根据 format字符串格式化数据,然后将结果输出到 filepath 文件中,指定出现字符串结束符 '\0'为止。
int fprintf(FILE * filepath, const char * format, ...);
//从 filepath 读取字符串,并根据format字符串来格式化数据。
int fscanf(FILE * filepath, const char * format, ...);

//案例 拷贝一个文件,并且修改内容格式
FILE *file = fopen("hello.txt", "r+");
FILE *new = fopen("new.txt", "w+");
char buf[100] = {
   0};
while (!feof(file))
{
   
    memset(buf, 0, sizeof(buf));
    int len=fscanf(file, "%s",buf);
    if(len>0)
    {
   
        fprintf(new,"name is %s\n",buf);
        printf("%s\n",buf);
    }
}
fclose(file);
fclose(new);

fread()/fwrite()

以数据块的方式读写文件

#include <stdio.h>
//将 filepath 的内容拷贝到 ptr 缓冲区中,如果缓冲区是char数组,那么size为1,nmemb为数组长度
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *filepath);
//将 ptr 缓冲区的内容拷贝到 filepath 中,如果缓冲区是char数组,那么size为1,nmemb为数组的内容长度
size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *filepath);

//案例  拷贝一张图片
FILE * bili = fopen("bilibili.png","rb");
FILE * cop = fopen("copy.png","wb");

char buf[1024]={
   0};
long sum=0;
while(!feof(bili))
{
       
    memset(buf,0,sizeof(buf));
    int ret = fread(buf,1,sizeof(buf),bili);
    printf("read size is:%d\n",ret);
    sum+=ret;
    long pos=ftell(bili);
    printf("pos is:%ld,  sum is:%ld\n",pos,sum);
    fwrite(buf,1,ret,cop);
}
fclose(bili);
fclose(cop);

fflush()

读写缓冲器更新,常用于文件读写到缓冲区后立即输出到文件中,而不是等程序结束去刷新。

#include <stdio.h>
//更新缓冲区数据到文件中保存,避免断电丢失
int fflush(FILE *stream);

4. 其他

stat()/fstat()

获取文件状态信息

#include <sys/types.h>
#include <sys/stat.h>
//filepath 文件路径
//buf 保存文件信息的结构体
int stat(const char *filepath, struct stat *buf);
//fd 是文件描述符
int fstat(int fd, struct stat *statbuf);

//stat结构体定义
struct stat {
   
    dev_t     st_dev;         /* ID of device containing file */
    ino_t     st_ino;         /* Inode number */
    mode_t    st_mode;        /* File type and mode */
    nlink_t   st_nlink;       /* Number of hard links */
    uid_t     st_uid;         /* User ID of owner */
    gid_t     st_gid;         /* Group ID of owner */
    dev_t     st_rdev;        /* Device ID (if special file) */
    off_t     st_size;        /* 总大小Total size, in bytes */
    blksize_t st_blksize;     /* 文件块大小 Block size for filesystem I/O */
    blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */

    /* Since Linux 2.6, the kernel supports nanosecond
       precision for the following timestamp fields.
       For the details before Linux 2.6, see NOTES. */

    struct timespec st_atim;  /* Time of last access */
    struct timespec st_mtim;  /* Time of last modification */
    struct timespec st_ctim;  /* Time of last status change */

#define st_atime st_atim.tv_sec      /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};


//案例 使用 fstat 输出文件属性
FILE * file = fopen("test.txt","r");
struct stat fileStat;

fstat(file->_fileno,&fileStat);

printf("%ld\n",fileStat.st_size);

fclose(file);

remove()

删除文件

#include <stdio.h>
int remove(const char *pathname);

rename()

文件更名

#include <stdio.h>
//oldpath 当前文件名 ;   newpath 新文件名 相对路径或者绝对路径
int rename(const char *oldpath, const char *newpath);
目录
相关文章
|
27天前
|
存储 C语言
【c语言】玩转文件操作
本文介绍了C语言中文件操作的基础知识,包括文件的打开和关闭、文件的顺序读写、文件的随机读写以及文件读取结束的判定。详细讲解了`fopen`、`fclose`、`fseek`、`ftell`、`rewind`等函数的使用方法,并通过示例代码展示了如何进行文件的读写操作。最后,还介绍了如何判断文件读取结束的原因,帮助读者更好地理解和应用文件操作技术。
35 2
|
1月前
|
存储 C语言
C语言文件操作(2)
【10月更文挑战第2天】
|
1月前
|
程序员 编译器 C语言
C语言底层知识------文件操作
本文详细介绍了文件操作的基本概念,包括文件的分类(程序文件和数据文件,其中着重于数据文件的文本文件和二进制文件),流的概念及其在C程序中的应用,以及标准输入输出流stdin、stdout和stderr的作用。作者通过示例展示了如何使用fopen、fclose和常见的读写函数如fgetc、fputc和fgets进行文件操作。
22 2
|
2月前
|
C语言
C语言——文件操作
本文介绍了文件的基本操作,包括文件的打开、关闭、读取和写入。使用`fopen`函数以不同模式(如“r”、“w”等)打开文件,并通过`fclose`关闭。文章详细解释了如何利用`fputc`、`fputs`及`fprintf`进行格式化写入,同时介绍了`fgetc`、`fgets`和`fscanf`用于文件内容的读取。此外,还涵盖了二进制文件的读写方法以及如何通过`fseek`、`ftell`和`rewind`实现文件的随机访问。
51 1
C语言——文件操作
|
1月前
|
存储 缓存 编译器
文件操作——C语言
文件操作——C语言
|
1月前
|
存储 C语言
简述C语言文件操作
简述C语言文件操作
11 0
|
1月前
|
存储 文件存储 C语言
深入C语言:文件操作实现局外影响程序
深入C语言:文件操作实现局外影响程序
|
1月前
|
存储 程序员 编译器
C语言文件操作(1)
【10月更文挑战第1天】
|
1月前
|
存储 C语言
C语言的文件操作
C语言的文件操作
22 0
|
1月前
|
存储 移动开发 Unix
C 语言文件操作详解
C 语言文件操作详解