WEB开发网
开发学院软件开发VC FMD开发文集 -- CArchive原理 阅读

FMD开发文集 -- CArchive原理

 2010-03-28 20:34:54 来源:WEB开发网   
核心提示:五.指定长度数据段落的读写以下分析UINT Read(void* lpBuf, UINT nMax); 读取长度为nMax的数据void Write(const void* lpBuf, UINT nMax); 写入指定长度nMax的数据对于大段数据的读写,先使用当前缓冲区中的内容或空间读取或写入,FMD开发文集 --

五.指定长度数据段落的读写

以下分析

UINT Read(void* lpBuf, UINT nMax); 读取长度为nMax的数据

void Write(const void* lpBuf, UINT nMax); 写入指定长度nMax的数据

对于大段数据的读写,先使用当前缓冲区中的内容或空间读取或写入,若这些空间够用了,则结束。

否则,从剩余的数据中找出最大的缓冲区整数倍大小的一块数据,直接读写到存储煤质(不反复使用缓冲区)。

剩余的余数部分,再使用缓冲区读写。

(说明:缓冲区读写的主要目的是将零散的数据以缓冲区大小为尺度来处理。对于大型数据,其中间的部分,不是零散的数据,使用缓冲区已经没有意思,故直接读写)

①读取

UINT CArchive::Read(void* lpBuf, UINT nMax)
{
  ASSERT_VALID(m_pFile);
  if (nMax == 0)
    return 0;
  UINT nMaxTemp = nMax; //还需要读入的长度,读入一部分,就减相应数值,直到此数值变为零
  
  //处理当前缓冲区中剩余部分。
  //如果要求读入字节小于缓冲区中剩余部分,则第一部分为要求读入的字节数,
  //否则读入全部剩余部分  
  UINT nTemp = min(nMaxTemp, (UINT)(m_lpBufMax - m_lpBufCur)); 
  memcpy(lpBuf, m_lpBufCur, nTemp);
  m_lpBufCur += nTemp;
  lpBuf = (BYTE*)lpBuf + nTemp; //移动读出内容所在区域的指针
  nMaxTemp -= nTemp;
  //当前缓冲区中剩余部分不够要求读入的长度。
  //还有字节需要读,则需要根据需要执行若干次填充缓冲区,读出,直到读出指定字节。
  if (nMaxTemp != 0) 
  {
    //计算出去除尾数部分的字节大小(整数个缓冲区大小)
    //对于这些部分,字节从文件对象中读出,放到输出缓冲区
    nTemp = nMaxTemp - (nMaxTemp % m_nBufSize); 
    UINT nRead = 0;
    UINT nLeft = nTemp;
    UINT nBytes;
    do
    {
      nBytes = m_pFile-> Read(lpBuf, nLeft); //要求读入此整数缓冲区部分大小
      lpBuf = (BYTE*)lpBuf + nBytes;
      nRead += nBytes;
      nLeft -= nBytes;
    }
    while ((nBytes > 0) && (nLeft > 0)); 知道读入了预定大小,或到达文件尾
    nMaxTemp -= nRead;
    if (nRead == nTemp) //读入的字节等于读入的整数倍部分 该读最后的余数部分了
    {
      // 建立装有此最后余数部分的内容的CArchive的工作缓冲区。
      if (!m_bDirectBuffer)
      {
        UINT nLeft = max(nMaxTemp, (UINT)m_nBufSize);
        UINT nBytes;
        BYTE* lpTemp = m_lpBufStart;
        nRead = 0;
        do
        {
          nBytes = m_pFile-> Read(lpTemp, nLeft); //从文件中读入到CArchive缓冲区
          lpTemp = lpTemp + nBytes;
          nRead += nBytes;
          nLeft -= nBytes;
        }
        while ((nBytes > 0) && (nLeft > 0) && nRead < nMaxTemp);
        m_lpBufCur = m_lpBufStart;
        m_lpBufMax = m_lpBufStart + nRead;
      }
      else
      {
        nRead = m_pFile-> GetBufferPtr(CFile::bufferRead, m_nBufSize,
          (void**)&m_lpBufStart, (void**)&m_lpBufMax);
        ASSERT(nRead == (UINT)(m_lpBufMax - m_lpBufStart));
        m_lpBufCur = m_lpBufStart;
      }
      //读出此剩余部分到输出
      nTemp = min(nMaxTemp, (UINT)(m_lpBufMax - m_lpBufCur));
      memcpy(lpBuf, m_lpBufCur, nTemp);
      m_lpBufCur += nTemp;
      nMaxTemp -= nTemp;
    }
    
  }
  return nMax - nMaxTemp;
}
②保存,写入void CArchive::Write(const void* lpBuf, UINT nMax)
{
  if (nMax == 0)
    return;
  
  //读入可能的部分到缓冲区当前的剩余部分  
  UINT nTemp = min(nMax, (UINT)(m_lpBufMax - m_lpBufCur));
  memcpy(m_lpBufCur, lpBuf, nTemp);
  m_lpBufCur += nTemp;
  lpBuf = (BYTE*)lpBuf + nTemp;
  nMax -= nTemp;
  if (nMax > 0) //还有未写入的部分
  {
    Flush();  //将当前缓冲区写入到存储煤质
    //计算出整数倍缓冲区大小的字节数
    nTemp = nMax - (nMax % m_nBufSize);
    m_pFile-> Write(lpBuf, nTemp); //直接写到文件
    lpBuf = (BYTE*)lpBuf + nTemp;
    nMax -= nTemp;
    //剩余部分添加到缓冲区
    if (m_bDirectBuffer)
    {
      // sync up direct mode buffer to new file position
      VERIFY(m_pFile-> GetBufferPtr(CFile::bufferWrite, m_nBufSize,
        (void**)&m_lpBufStart, (void**)&m_lpBufMax) == (UINT)m_nBufSize);
      ASSERT((UINT)m_nBufSize == (UINT)(m_lpBufMax - m_lpBufStart));
      m_lpBufCur = m_lpBufStart;
    }
    // copy remaining to active buffer
    ASSERT(nMax < (UINT)m_nBufSize);
    ASSERT(m_lpBufCur == m_lpBufStart);
    memcpy(m_lpBufCur, lpBuf, nMax);
    m_lpBufCur += nMax;
  }
}

上一页  1 2 3 4 5 6  下一页

Tags:FMD 开发 文集

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接