封装文件操作类

  经常要用到文件操作,所以想要将文件操作封装起来,方便后面的使用。
文件操作包含的基本操作有:打开文件,对文件进行写操作,对文件进行读操作,还有关闭文件。现在就对这几个操作封装。

1.成员变量

  如果要进行封装,那么成员变量有哪些?这是一个文件基本操作类,这些基本操作都要用到的变量是什么?

1.1 文件指针

  先分析一下这些基本操作有什么特点。

FILE *fopen( const char * filename, const char * mode );  // 打开文件,返回文件指针
int fprintf(FILE *fp, const char *format, ...);  // 写操作
char *fgets(char *buf, int size, FILE *fp);   //读操作
int fclose(FILE *fp);   // 关闭文件

  会发现这些操作都离不开一个变量,那就是文件指针,所以它就作为成员变量。

1.2 文件缓冲区

  对操作文件的时候,C语言为文件分配一个信息区,该信息区包含文件描述信息、缓冲区位置、缓冲区大小、文件读写到的位置等基本信息。文件进行读写操作,是先将数据读写到缓冲区中,所以第2个成员变量是缓冲区。

private:
  FILE *m_fp;        // 文件指针
  bool  m_bEnBuffer; // 是否启用缓冲区,true-启用;false-不启用

2.成员函数

  成员函数,首先想到的便是构造函数和析构函数。文件的基本操作有打开和关闭文件,对文件进行读和写。分析了应该具有什么函数,接下来就来分析怎么来声明这些函数。一个函数包括:函数名,返回值,参数列表,还有函数体

2.1 构造函数

  构造函数负责对类的成员变量进行初始化

 
CFile::CFile()   // 类的构造函数
{
  m_fp=0;
  m_bEnBuffer=true;
}

2.2 析构函数

  析构函数通常用来释放资源,但是释放资源我将它放在Close函数里面

 
CFile::~CFile()   // 类的析构函数
{
  Close();  // 调用Close释放资源
}

2.3 Close函数

  这个函数通常是用来关闭文件的,一般不会有错误,所以可以不用返回值。因为它只是关闭文件,只用到文件指针这个变量,而Close()和文件指针是在同一个类里面的,所以不需要到其他的变量,所以参数列表为空。

// 关闭文件指针
void CFile::Close()
{
  if (m_fp!=0) fclose(m_fp);  // 关闭文件指针
  m_fp=0;
}

2.4 Open函数

  这个函数是用来打开文件的。

  (1)分析一下返回值,打开文件,有时候可能会打开失败,所以要有一个返回值来提示调用者是否打开文件成功。这个返回值用bool类型的就可以了,返回true和false就很直接明了。

  (2)函数的参数:这个函数是用来打开文件的,要有文件名(文件在这封装没有作为成员变量)才能打开,调用的时候调用者要给它一个文件名。所以参数列表要有文件名(文件名一般是字符串类型)。

  调用者在调用的时候除了要指定文件名,还应该有什么?还应该有一个打开的模式。所以另一个参数是打开的模式。

  (3)函数体就是利用库函数里面的fopen函数打开文件,不过还要注意一些细节的问题。比如说要打开新的文件,但是已经打开了别的文件,就要先关闭。

// 打开文件,参数与fopen相同,打开成功true,失败返回false         
bool CFile::Open(const char *filename,const char *openmode)
{
  Close();  // 打开新的文件之前,如果已经打开了文件,关闭它。
 
  if ( (m_fp=fopen(filename,openmode)) == 0 ) return false;
 
  return true;
}

2.5 Fprintf函数

  这个函数用来向文件写入文本数据。
  (1)函数的返回值,这里偷懒一下,设置为void。哈哈哈
  (2)参数是可变参数
  (3)函数体:注意细节,这个函数要对指针进行操作,所以要判断一下指针是否为空,防止对空指针操作。

// 调用fprintf向文件写入数据
void CFile::Fprintf(const char *fmt,...)
{
  if ( m_fp == 0 ) return;
 
  va_list arg;
  va_start(arg,fmt);
  vfprintf(m_fp,fmt, arg);
  va_end(arg);
 
  if ( m_bEnBuffer == false ) fflush(m_fp);
}

2.6 Fgets 函数

  这个函数用于从文件中读取一行。

  (1)返回值:设置为bool类型,便于查看是否读取成功。

  (2)参数列表:从文件中读取一行数据,那么这一行数据要有地方来存放,所以设置一个字符串来暂时存放读取出来的这一行数据。

还有一个问题这一行数据有多大,还要设置一个参数来限定每次读取的大小。

  (3)函数体:要对指针操作,所以要防止对空指针进行操作。
还有一个用于暂时存放数据的字符串(每次取出来都放在它这里),所以每次是以前记得初始化。

// 调用fgets从文件中读取一行
bool CFile::Fgets(char *strBuffer,const int ReadSize)
{
  if ( m_fp == 0 ) return false;
 
  memset(strBuffer,0,ReadSize);
 
  if (fgets(strBuffer,ReadSize,m_fp) == 0) return false;
 
  return true;
}

3.CFile类及测试代码

3.1 封装好的类

#include <stdio.h>
#include <string.h>
#include <stdarg.h>
 
// 文件操作类声明
class CFile
{
private:
  FILE *m_fp;        // 文件指针
  bool  m_bEnBuffer; // 是否启用缓冲区,true-启用;false-不启用
 
public:
  CFile();   // 类的构造函数
 
 
 ~CFile();   // 类的析构函数
 

  // 打开文件,参数与fopen相同,打开成功true,失败返回false         
  bool Open(const char *filename,const char *openmode);
 
  // 调用fprintf向文件写入数据
  void Fprintf(const char *fmt,... );
 
  // 调用fgets从文件中读取一行
  bool Fgets(char *strBuffer,const int ReadSize);
 
  // 关闭文件指针
  void Close();
};
 

 
CFile::CFile()   // 类的构造函数
{
  m_fp=0;
  m_bEnBuffer=true;
}
 

// 关闭文件指针
void CFile::Close()
{
  if (m_fp!=0) fclose(m_fp);  // 关闭文件指针
  m_fp=0;
}
 
CFile::~CFile()   // 类的析构函数
{
  Close();  // 调用Close释放资源
}
 

 
// 打开文件,参数与fopen相同,打开成功true,失败返回false         
bool CFile::Open(const char *filename,const char *openmode)
{
  Close();  // 打开新的文件之前,如果已经打开了文件,关闭它。
 
  if ( (m_fp=fopen(filename,openmode)) == 0 ) return false;
 
  return true;
}
 
// 调用fprintf向文件写入数据
void CFile::Fprintf(const char *fmt,...)
{
  if ( m_fp == 0 ) return;
 
  va_list arg;
  va_start(arg,fmt);
  vfprintf(m_fp,fmt, arg);
  va_end(arg);
 
  if ( m_bEnBuffer == false ) fflush(m_fp);
}
 
// 调用fgets从文件中读取一行
bool CFile::Fgets(char *strBuffer,const int ReadSize)
{
  if ( m_fp == 0 ) return false;
 
  memset(strBuffer,0,ReadSize);
 
  if (fgets(strBuffer,ReadSize,m_fp) == 0) return false;
 
  return true;
}

3.2 测试代码

int main(int argc,char *argv[])
{
  if (argc !=2) { printf("请输入待打开的文件名。\n"); return -1; }
 
  CFile File;
 
  if (File.Open(argv[1],"r")==false) { printf("File.Open(%s)失败。\n",argv[1]); return -1; }
 
  char strLine[301];
 
  while (true)
  { // 从文件中读取每一行
    if (File.Fgets(strLine,300)==false) break;
 
    printf("%s",strLine);   // 把从文件中读到的内容显示到屏幕
  }
}

测试结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值