📄 filestreamopt.cpp
字号:
//---------------------------------------------------------------------------
//程序设计:金旭亮
//最新修改时间:2001年9月27日
//
//功能:用于实现对文件流的操作
//
//备注:
//1.所有操作都是在内存中进行的,
// 所以,要在最后调用CloseStream()方法保存到文件中
//----------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "FileStreamOpt.h"
//---------------------------------------------------------------------------
__fastcall FileStreamOpt::FileStreamOpt()
{
}
//---------------------------------------------------------------------------
__fastcall FileStreamOpt::~FileStreamOpt()
{
}
#pragma package(smart_init)
TFileStream * __fastcall FileStreamOpt::OpenFileStream(String FileName, String OpenMode)
{
//按文件名和打开方式打开文件,返回流的指针,在内部
//创建一个流对象,失败返回NULL。
//
//前提:
//1.要读的文件必须存在;
//2.要写的文件必须不为只读、隐藏和系统属性
//3.要读写的文件必须存在
//4.文件打开方式字串必须是Create,Read,Write三者的组合
//
//结果:
//如果一切正常返回流指针
//否则:给出提示后返回NULL.
//
//注意:
//当采用Create方式时,将覆盖同名文件.可根据需要去掉ShowMessage语句
TFileStream *pFile;
//对文件属性进行先期判断
bool IsExists=false;
bool IsHidden=false;
bool IsReadOnly=false;
bool IsSystem=false;
IsExists=FileExists(FileName);
int Attrs = FileGetAttr(FileName);
if (Attrs & faHidden)
IsHidden=true;
if (Attrs & faReadOnly)
IsReadOnly=true;
if (Attrs & faSysFile)
IsSystem=true;
//为简化比较,将输入的文件打开方式字串除去空格并转为大写.
OpenMode=OpenMode.Trim();
OpenMode=OpenMode.UpperCase();
//为了避免传入无效的打开字串,设计一个Bool变量
bool Valid;
Valid=false;
try
{
if(OpenMode=="READ") //打开文件读
{
if(IsExists==false)
{
ShowMessage("文件:"+FileName+"没找到!");
return NULL;
}
pFile=new TFileStream(FileName,fmOpenRead);
Valid=true;
}
if(OpenMode=="WRITE") //打开文件写
{
if(IsExists==false)
{
ShowMessage("文件:"+FileName+"没找到!");
return NULL;
}
if(IsReadOnly || IsSystem || IsHidden)
{
ShowMessage("文件:"+FileName+"不允许更改!");
return NULL;
}
pFile=new TFileStream(FileName,fmOpenWrite);
Valid=true;
}
if((OpenMode=="READWRITE")||(OpenMode=="WRITEREAD")) //打开文件读写
{
if(IsExists==false)
{
ShowMessage("文件:"+FileName+"没找到!");
return NULL;
}
if(IsReadOnly || IsSystem || IsHidden)
{
ShowMessage("文件:"+FileName+"不允许更改!");
return NULL;
}
pFile=new TFileStream(FileName,fmOpenReadWrite);
Valid=true;
}
if(OpenMode=="CREATEREAD") //创建一个文件读
{
if(IsExists)
{
ShowMessage("文件:"+FileName+"已经存在,将被替换!");
}
pFile=new TFileStream(FileName,fmCreate|fmOpenRead);
Valid=true;
}
if(OpenMode=="CREATEWRITE") //创建一个文件写
{
if(IsExists)
{
ShowMessage("文件:"+FileName+"已经存在,将被替换!");
}
pFile=new TFileStream(FileName,fmCreate|fmOpenWrite);
Valid=true;
}
if((OpenMode=="CREATEREADWRITE")||(OpenMode=="CREATEWRITEREAD")) //创建一个文件读写
{
if(IsExists)
{
ShowMessage("文件:"+FileName+"已经存在,将被替换!");
}
pFile=new TFileStream(FileName,fmCreate|fmOpenReadWrite);
Valid=true;
}
if(Valid==false)
{
ShowMessage("传入了无效的文件打开模式字串");
return NULL;
}
return pFile; //返回流的指针
}
catch(...)
{
return NULL;
}
}
void __fastcall FileStreamOpt::CloseStream(TStream *pStream)
{
//关闭指定的流
pStream->Free ();
}
bool __fastcall FileStreamOpt::AppendStream(TStream * pStreamFirst, TStream * pStreamSecond)
{
//在已有流pStreamFirst的未尾加入一个新流pStreamSecond
//
//前提:
//1.两个参数所代表的均为有效流
//结果:
//成功返回True
//
//注意:
//第二个流是从当前位置到流的结尾开始添加的,如果需要全部
//追加第二个流,则应在调用此函数之前,将其读写指针移到头
try
{
//将第一个流移到末尾
pStreamFirst->Seek(0,soFromEnd);
//执行添加操作
int ret=pStreamFirst->CopyFrom(pStreamSecond,pStreamSecond->Size-pStreamSecond->Position);
if(ret==0)
{
return false;
}
}
catch(...)
{
return false;
}
return true;
}
bool __fastcall FileStreamOpt::ExtractStream(TStream * pStream, String NewFileName, int begin, int size,bool OverCover)
{
//从一个现成流pStream中抽取出一部分(从begin到begin+size),成为新流,并存为指定的文件NewFileName。
//成功返回True
//
//前提:
//1.Begin应小于流的尺寸
//2.当文件存在时,根据OverCover决定是否替换,当不能替换时(如文件只读)
// 给出提示后放弃操作
//
//结果:
//成功返回True
//
//注意:
//可能失败的原因:内存分配和操作失败
if(FileExists(NewFileName)&& OverCover)
{
bool ret=DeleteFile(NewFileName);
if(ret==false) //可能是只读文件
{
ShowMessage("文件:"+NewFileName+"已经存在,且无法删除");
return false;
}
}
//有同名文件且不需要删除
if(FileExists(NewFileName)&& !OverCover)
{
ShowMessage("文件:"+NewFileName+"已经存在");
return false;
}
TFileStream *pNewFile;
pNewFile=OpenFileStream(NewFileName,"createWrite");
if(pNewFile==NULL) //不能创建文件
return false;
if(pStream->Size<begin) //检查尺寸大小
return false;
try
{
//移到合适的位置
pStream->Seek(begin,soFromBeginning);
//分配内存
void *buf=new char[size];
if(buf==NULL)
{
ShowMessage("内存不足");
return false;
}
pStream->Read(buf,size); //将流的内容读入缓冲区
pNewFile->Seek(0,soFromBeginning);
pNewFile->Write(buf,size); //写入新流
pNewFile->Free(); //写入文件
}
catch(...)
{
return false;
}
return true;
}
bool __fastcall FileStreamOpt::CutOutStream(TStream* pStream,int begin, int size)
{
//将一个流从中间截去部分内容,成功返回True
//前提:
//1.begin+size必须小于流的尺寸,当此情况发生时,不引发错误,而仅将流从begin处截到尾
//2.begin必须小于流的尺寸,当此情况发生时,提前返回
//注意:
//由于此函数进行了多次内存流操作,所以可能很花时间。
//可能发生错误之处就是内存流的替换复制操作。
//复杂之处在于内存流不能直接转换为文件流,必须要用CopyFrom操作。
int len=pStream->Size ; //获取流的长度
int tail=len-begin-size; //截取流后部分的长度
if(tail<0)
tail=0;
if(begin>len)
{
return false;
}
try
{
//创建一个内存流,以供临时存放流用
TMemoryStream *pTemp=new TMemoryStream();
pTemp->Size=0;
//临时流移到开头
pTemp->Seek (0,soFromBeginning);
//数据流移到开头
pStream->Seek(0,soFromBeginning);
//临时流复制数据流的开始部分,并保证移到位
if(begin!=0)
pTemp->CopyFrom(pStream,begin);
//数据流跳过要载取的部分
pStream->Seek(begin+size,soFromBeginning);
//临时流复制余下的部分
if(tail!=0)
pTemp->CopyFrom(pStream,tail);
//清空数据流
pStream->Size=0;
//重新获取流
//临时流移到开头
pTemp->Seek (0,soFromBeginning);
pStream->CopyFrom(pTemp,pTemp->Size);
}
catch(...)
{
ShowMessage("当进行内存流操作时发生错误");
return false;
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -