导航
  • 主页
  • VC综合技术
  • 互联网技术
  • MFC AppLauncher
  • .NET 技术
  • 界面
  • 进程
  • 算法
  • 硬件/系统
  • 数据库
  • VC++技术资源

关于CArchive的小问题

zjfhgdx 2009-08-21 08:20:38
一:
我知道CFile有getlenth()可以得到文件的长度。
但CArchive是怎样才能得到文件长度。

因为我想用
while(remaining)
{
...
remaining-=siaeof(int)
}
的方法把数据一个个读到内存。

二:
如果CArchive所指文件是空的,当使用int A; ar>>A;时会发生什么?
...全文
137 点赞 收藏 9
写回复
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
TearyWang 2009-08-22
细看一下#6楼的摘出的源代码,不但可以找到答案,或者能使你更深入地理解CArchive。
回复
zjfhgdx 2009-08-21
2. “如果CArchive所指文件是空的,当使用int A; ar>>A;时会发生什么?”所指文件是空的是什么意思?是指文件指针是NULL,还是文件中没有数据?

我的意思是文件中的数据是空的
回复
zjfhgdx 2009-08-21
晚上去试试。
回复
TearyWang 2009-08-21
1. 取得文件长度:m_Archive.GetFile()->GetLength();
2. “如果CArchive所指文件是空的,当使用int A; ar>>A;时会发生什么?”所指文件是空的是什么意思?是指文件指针是NULL,还是文件中没有数据? 若是文件指针为NULL,则CArchive对象无法成功构造。所有的 << 或 >> 操作,在CArchive中,都是对缓存进行的,或者是用户缓存,或者是CArchive缓存,或者是文件缓存。在 >> 操作中,当需要读取的数据小于缓存中剩余字节的大小,CArchive将调用文件指针(CFile指针),从文件中读入数据。看一下以下的源代码:


// 摘自 afx.inl
_AFX_INLINE CArchive& CArchive::operator>>(int& i)
{ return CArchive::operator>>((LONG&)i); }

_AFX_INLINE CArchive& CArchive::operator>>(LONG& l)
{
if(!IsLoading())
AfxThrowArchiveException(CArchiveException::writeOnly,m_strFileName);
if (m_lpBufCur + sizeof(LONG) > m_lpBufMax)
FillBuffer(UINT(sizeof(LONG) - (m_lpBufMax - m_lpBufCur)));
l = *(UNALIGNED LONG*)m_lpBufCur; m_lpBufCur += sizeof(LONG); return *this;
}

// 摘自arccore.cpp
void CArchive::FillBuffer(UINT nBytesNeeded)
{
ASSERT_VALID(m_pFile);
ASSERT(IsLoading());

if(!IsLoading())
AfxThrowArchiveException(CArchiveException::writeOnly,m_strFileName);

ASSERT(m_bDirectBuffer || m_lpBufStart != NULL);
ASSERT(m_bDirectBuffer || m_lpBufCur != NULL);
ASSERT(nBytesNeeded > 0);
ASSERT(nBytesNeeded <= (UINT)m_nBufSize);
ASSERT(m_lpBufStart == NULL ||
AfxIsValidAddress(m_lpBufStart, UINT(m_lpBufMax - m_lpBufStart), FALSE));
ASSERT(m_lpBufCur == NULL ||
AfxIsValidAddress(m_lpBufCur, UINT(m_lpBufMax - m_lpBufCur), FALSE));

UINT nUnused = UINT(m_lpBufMax - m_lpBufCur);
ULONG nTotalNeeded = ((ULONG)nBytesNeeded) + nUnused;

// fill up the current buffer from file
if (!m_bDirectBuffer)
{
ASSERT(m_lpBufCur != NULL);
ASSERT(m_lpBufStart != NULL);
ASSERT(m_lpBufMax != NULL);

if (m_lpBufCur > m_lpBufStart)
{
// copy unused
if ((int)nUnused > 0)
{
Checked::memmove_s(m_lpBufStart, (size_t)(m_lpBufMax - m_lpBufStart),
m_lpBufCur, nUnused);
m_lpBufCur = m_lpBufStart;
m_lpBufMax = m_lpBufStart + nUnused;
}

// read to satisfy nBytesNeeded or nLeft if possible
UINT nRead = nUnused;
UINT nLeft;
UINT nBytes;

// Only read what we have to, to avoid blocking waiting on data
// we don't need
if (m_bBlocking)
nLeft = nBytesNeeded-nUnused;
else
nLeft = m_nBufSize-nUnused;
BYTE* lpTemp = m_lpBufStart + nUnused;
do
{
nBytes = m_pFile->Read(lpTemp, nLeft);
lpTemp = lpTemp + nBytes;
nRead += nBytes;
nLeft -= nBytes;
}
while (nBytes > 0 && nLeft > 0 && nRead < nTotalNeeded);

m_lpBufCur = m_lpBufStart;
m_lpBufMax = m_lpBufStart + nRead;
}
}
else
{
// seek to unused portion and get the buffer starting there
if (nUnused != 0)
m_pFile->Seek(-(LONG)nUnused, CFile::current);
UINT nActual = m_pFile->GetBufferPtr(CFile::bufferRead, m_nBufSize,
(void**)&m_lpBufStart, (void**)&m_lpBufMax);
ASSERT(nActual == (UINT)(m_lpBufMax - m_lpBufStart));
m_lpBufCur = m_lpBufStart;
}

// not enough data to fill request?
if ((ULONG)(m_lpBufMax - m_lpBufCur) < nTotalNeeded)
AfxThrowArchiveException(CArchiveException::endOfFile);
}
回复
heiheizh618 2009-08-21
我想到一个非主流的方法针对楼主的第一个问题。。
继承CArchive。
然后给你需要的类设置友元,或者设计几个函数分别获取m_lpBufCur,m_lpBufMax,m_lpBufStart; 因为这三个指针在CArchive中都是protected。
然后判断m_lpBufCur==m_lpBufMax;
你再设计自己的函数,每取一个数m_lpBufCur移多少位。。
这个方法没有经过证实。。如果不对的话就无视吧。。
回复
churenxh 2009-08-21
http://www.0591360.com/0591360/classnews.asp?wz_id=457
回复
lygfqy 2009-08-21
空的貌似就是不赋值了,保持原来的值
回复
zjfhgdx 2009-08-21
2.文件有一个指针,由CFile::GetPosition获取,ar>>A会定向输入至文件的指针处,在调用CArchive::Flush后会将指针后面的数据覆盖。

//这个我的意思是。。。AR是一个CARCHIVE对象,我是从AR中提出数据到变量A中,但是AR中的数据是空的。
这会产生什么后果

回复
雪影 2009-08-21
1.CArchive不能获取文件的长度,必须通过CFile对象才能获取
2.文件有一个指针,由CFile::GetPosition获取,ar>>A会定向输入至文件的指针处,在调用CArchive::Flush后会将指针后面的数据覆盖。
回复
发动态
发帖子
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……