LPSTREAM 将整个 Stream 内容读入 unsigned char* 数组
LPSTREAM Read entire Stream contents into unsigned char* array
我在复合存储中有一个流。我想将它的数据读入一个字节数组。我对我需要在 lpSrc->Read() 的第二个参数中放入什么感到困惑。我想将整个文件读入我的 unsigned char* (byte*) 数组:
unsigned char* rawData;
LPSTREAM lpSrc = NULL;
HRESULT hrRet = STG_E_INVALIDPARAMETER;
TRY
{
USES_CONVERSION;
HRESULT hrSrc = pStg->GetStg()->OpenStream(CT2COLE(szStream),
NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE,
0,
&lpSrc);
if (hrSrc != NOERROR)
{
hrRet = hrSrc;
}
else
{
ULONG ul;
hrRet = lpSrc->Read(rawData, /*???*/, &ul);
}
}
CATCH_ALL(e)
{
hrRet = STG_E_UNKNOWN;
}
END_CATCH_ALL
我已经尝试过很多读取流的变体,所以我不完全确定这是我首先应该做的方式。我该如何解决这个问题?
I'm confused about what I need to put in the second parameter of lpSrc->Read().
答案在文档中:
ISequentialStream::Read method
pv [out]
A pointer to the buffer which the stream data is read into.
cb [in]
The number of bytes of data to read from the stream object.
pcbRead [out]
A pointer to a ULONG variable that receives the actual number of bytes read from the stream object.
您必须指定要从流中读取到缓冲区中的字节数。
I want to read the ENTIRE file into my unsigned char* (byte*) array:
这意味着您必须首先知道流中有多少字节可用。你可以从 IStream::Stat()
方法中得到它。然后,您必须先将 rawData
缓冲区分配到该大小,然后才能将数据读入缓冲区。
尝试这样的事情:
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)(-1))
#endif
unsigned char* rawData;
LPSTREAM lpSrc = NULL;
HRESULT hrRet = STG_E_INVALIDPARAMETER;
TRY
{
USES_CONVERSION;
hrRet = pStg->GetStg()->OpenStream(
CT2COLE(szStream),
NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE,
0,
&lpSrc);
if (hrRet == S_OK)
{
STATSTG stat;
hrRet = lpSrc->Stat(&stat, STATFLAG_NONAME);
if (hrRet == S_OK)
{
if (stat.cbSize.QuadPart > SIZE_MAX)
{
hrRet = HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
}
else
{
size_t size = (size_t) stat.cbSize.QuadPart;
rawData = malloc(size);
if (!rawData)
{
hrRet = E_OUTOFMEMORY;
}
else
{
unsigned char *ptr = rawData;
size_t sizeLeft = size;
while (sizeLeft != 0)
{
ULONG ul;
hrRet = lpSrc->Read(ptr, (sizeLeft >= MAXDWORD) ? MAXDWORD : (DWORD) sizeLeft, &ul);
if (FAILED(hrRet) || (ul == 0)) break;
ptr += ul;
sizeLeft -= ul;
}
if (SUCCEEDED(hrRet))
{
if (sizeLeft != 0) size -= sizeLeft;
// use rawData up to size number of bytes as needed...
}
free(rawData);
}
}
}
lpSrc->Release();
}
}
CATCH_ALL(e)
{
hrRet = E_UNEXPECTED;
}
END_CATCH_ALL
我在复合存储中有一个流。我想将它的数据读入一个字节数组。我对我需要在 lpSrc->Read() 的第二个参数中放入什么感到困惑。我想将整个文件读入我的 unsigned char* (byte*) 数组:
unsigned char* rawData;
LPSTREAM lpSrc = NULL;
HRESULT hrRet = STG_E_INVALIDPARAMETER;
TRY
{
USES_CONVERSION;
HRESULT hrSrc = pStg->GetStg()->OpenStream(CT2COLE(szStream),
NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE,
0,
&lpSrc);
if (hrSrc != NOERROR)
{
hrRet = hrSrc;
}
else
{
ULONG ul;
hrRet = lpSrc->Read(rawData, /*???*/, &ul);
}
}
CATCH_ALL(e)
{
hrRet = STG_E_UNKNOWN;
}
END_CATCH_ALL
我已经尝试过很多读取流的变体,所以我不完全确定这是我首先应该做的方式。我该如何解决这个问题?
I'm confused about what I need to put in the second parameter of lpSrc->Read().
答案在文档中:
ISequentialStream::Read method
pv [out]
A pointer to the buffer which the stream data is read into.
cb [in]
The number of bytes of data to read from the stream object.
pcbRead [out]
A pointer to a ULONG variable that receives the actual number of bytes read from the stream object.
您必须指定要从流中读取到缓冲区中的字节数。
I want to read the ENTIRE file into my unsigned char* (byte*) array:
这意味着您必须首先知道流中有多少字节可用。你可以从 IStream::Stat()
方法中得到它。然后,您必须先将 rawData
缓冲区分配到该大小,然后才能将数据读入缓冲区。
尝试这样的事情:
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)(-1))
#endif
unsigned char* rawData;
LPSTREAM lpSrc = NULL;
HRESULT hrRet = STG_E_INVALIDPARAMETER;
TRY
{
USES_CONVERSION;
hrRet = pStg->GetStg()->OpenStream(
CT2COLE(szStream),
NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE,
0,
&lpSrc);
if (hrRet == S_OK)
{
STATSTG stat;
hrRet = lpSrc->Stat(&stat, STATFLAG_NONAME);
if (hrRet == S_OK)
{
if (stat.cbSize.QuadPart > SIZE_MAX)
{
hrRet = HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
}
else
{
size_t size = (size_t) stat.cbSize.QuadPart;
rawData = malloc(size);
if (!rawData)
{
hrRet = E_OUTOFMEMORY;
}
else
{
unsigned char *ptr = rawData;
size_t sizeLeft = size;
while (sizeLeft != 0)
{
ULONG ul;
hrRet = lpSrc->Read(ptr, (sizeLeft >= MAXDWORD) ? MAXDWORD : (DWORD) sizeLeft, &ul);
if (FAILED(hrRet) || (ul == 0)) break;
ptr += ul;
sizeLeft -= ul;
}
if (SUCCEEDED(hrRet))
{
if (sizeLeft != 0) size -= sizeLeft;
// use rawData up to size number of bytes as needed...
}
free(rawData);
}
}
}
lpSrc->Release();
}
}
CATCH_ALL(e)
{
hrRet = E_UNEXPECTED;
}
END_CATCH_ALL