现在的位置: 首页 > 综合 > 正文

一种读取文件的方式

2018年02月12日 ⁄ 综合 ⁄ 共 3234字 ⁄ 字号 评论关闭

每次读取文件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;
}

【上篇】
【下篇】

抱歉!评论已关闭.