一种读取文件的方式
来源:互联网 发布:太祖与太宗 知乎 编辑:程序博客网 时间:2024/06/04 20:01
每次读取文件1<<15个字节存在一个数组里面 然后调用子类的GetByte()获得一个字节 GetWord()获得双字节 即一个字
class RBaseStream
{
public:
RBaseStream();
virtual ~RBaseStream();
virtual bool Open(const char * filename);
virtual void Close();
void SetBlockSize(int block_size,int ubGetSize=4);
bool IsOpen();
void SetPos(int pos);
int GetPos();
void Skip(int bytes);
jmp_buf& JumBuf();
protected:
jmp_buf m_jmp_buf;
unsigned char* m_start;
unsigned char* m_end;
unsigned char* m_current;
FILE* m_file;
int m_unGetsize;
int m_block_size;
int m_block_pos;
bool m_jmp_set;
bool m_is_opened;
virtual void ReadBlock();
virtual void Release();
virtual void Allocate();
};
RBaseStream::RBaseStream()
{
m_start=m_end=m_current=0;
m_file=0;
m_block_size=1<<15;
m_unGetsize=4;
m_is_opened=false;
m_jmp_set=false;
}
void RBaseStream::Allocate()
{
if(!m_start)
{
m_start=new unsigned char[m_block_size+m_unGetsize];
m_start+=m_unGetsize;
}
m_end = m_start + m_block_size;
m_current = m_end;
}
void RBaseStream::ReadBlock()
{
unsigned int readed;
// assert( m_file != 0 );
if(m_start)
{
memcpy(m_start - m_unGetsize, m_end - m_unGetsize, m_unGetsize);
}
SetPos( GetPos() );
fseek(m_file , m_block_pos , SEEK_SET);
readed=fread( m_start, 1, m_block_size, m_file );
m_end = m_start + readed;
m_current -= m_block_size;
m_block_pos += m_block_size;
if(readed == 0 || m_current >= m_end)
{
if( m_jmp_set)
longjmp( m_jmp_buf, -123);
}
}
bool RBaseStream::Open( const char * filename )
{
Close();
Allocate();
m_file=fopen( filename, "rb" );
if( m_file )
{
m_is_opened = true;
SetPos(0);
}
return m_file != 0;
}
void RBaseStream::Close()
{
if(m_file)
{
fclose(m_file);
m_file = 0;
}
m_is_opened = false;
}
void RBaseStream::Release()
{
if( m_start )
{
delete [](m_start - m_unGetsize);
}
m_start = m_end = m_current = 0;
}
void RBaseStream::SetBlockSize(int block_size, int unGetsize)
{
if( m_start && block_size == m_block_size && unGetsize == m_unGetsize ) return;
Release();
m_block_size = block_size;
m_unGetsize = unGetsize;
Allocate();
}
void RBaseStream::SetPos(int pos)
{
int offset = pos & (m_block_size - 1); //经典必看 防止pos数据溢出
int block_pos = pos - offset;
if( m_current < m_end && block_pos == m_block_pos - m_block_size )
{
m_current = m_start + offset;
}
else
{
m_block_pos = block_pos;
m_current = m_start + m_block_size + offset;
}
}
int RBaseStream::GetPos()
{
return m_block_pos - m_block_size + (int)(m_current - m_start);
}
void RBaseStream::Skip(int bytes)
{
m_current += bytes;
}
jmp_buf& RBaseStream::JumBuf()
{
m_jmp_set=true;
return m_jmp_buf;
}
RBaseStream::~RBaseStream()
{
}
class RLByteStream : public RBaseStream
{
public:
int GetWord();
int GetByte();
virtual ~RLByteStream();
};
RLByteStream::~RLByteStream()
{
}
int RLByteStream::GetByte()
{
unsigned char *current = m_current;
int val;
if( m_current>=m_end)
{
ReadBlock();
current=m_current;
}
val = *( (unsigned char *)current);
m_current = current + 1;
return val;
}
int RLByteStream::GetWord()
{
unsigned char *current=m_current;
int val;
if(current+1 < m_end)
{
val = current[0] + (current[1] << 8);
m_current = current + 2;
}
else
{
val = GetByte();
val|= GetByte() << 8;
}
return val;
}
- 一种读取文件的方式
- 读取大excel文件的一种方式,利用PHPExcel读取
- 一种处理从文件读取整数的方式
- android 读取本地文件的一种方式
- Java读取csv文件的一种方法
- 属性文件的读取方式.
- properties文件的读取方式
- 常用的文件读取方式
- 读取properties文件的方式
- 读取属性文件的方式
- 读取xml文件的方式
- Android文件读取的方式
- 文件加密的一种方式-压缩
- android 4.0的一种拷贝文件方式
- 一种简单的c++文件操作方式
- 批量删除.svn文件的一种方式
- log4j.properties文件配置的一种方式
- web.xml文件的一种配置方式
- 五.redis pipeline
- 六.redis 发布订阅
- 七.redis 持久化
- 八.redis 主从复制
- 九.redis学习笔记之虚拟内存
- 一种读取文件的方式
- hdoj1229
- Android 自己制作的相册--效果还不错哦
- [转]Redis几个认识误区
- Latex交叉引用
- flex 编译函数
- 在Windows Server 2003下安装MySQL 5.5.9记录
- Concurrent LRU Block Cache in HBase
- Smoke Testing for Taiwan