资源而不是外部文件C ++

时间:2012-04-18 12:18:37

标签: c++ windows visual-studio file-io embedded-resource

我正在重用一些旧代码(最初在c上开发,而不是c ++)和一些函数来打开/读取/操作文本文件。文本文件的路径作为字符串(char *)传递给函数,然后使用:FileToUse = fopen(filename, "rb");打开,然后使用多次调用fread()fseek()。已知此代码适用于外部文本文件,但现在我想将textfiles作为资源包含在我的项目中(Visual Studio中的MFC C ++)。

我在网上找到了一些关于如何在此代码中使用资源的示例:

HINSTANCE hInst = AfxGetResourceHandle();
HRSRC hResource = FindResource(hInst, MAKEINTRESOURCE(IDR_TEXTFILE1), "TEXTFILE");

if (hResource){
  HGLOBAL hLoadedResource = LoadResource(hInst, hResource);
  if (hLoadedResource){
    const char* pResource = LockResource(hLoadedResource);
    if (pResource){
      DWORD dwResourceSize = SizeofResource(hInst, hResource);
      if (0 != dwResourceSize){                            // if(FileToUse){
        memcpy(&Buffer, pResource, (15 * 2));              //   fread($Buffer, 15, 2, FileToUse);
        pTemp = pResource + 200;                           //   fseek(FileToUse, 200, SEEK_SET);
        pTemp = pTemp + 100;                               //   fseek(FileToUse, 100, SEEK_CUR);
        pTemp = pResource + (dwResourceSize - 1) - 40;     //   fseek(FileToUse, -40, SEEK_END);
      }
    }
  }
}

我用memcpy()替换了fread调用,如图所示,但是我错过了fread(实际读取项)的返回值,并且在原始代码中fseek移动了filepointer,我想知道我的方法是否使用临时指针是正确的。

我的最终目标是使用类似的函数原型模拟fread和fseek对资源的调用:

size_t resread( void* buffer, size_t size, size_t count, char* resource );

int resseek( char* resource, long offset, int origin );

非常感谢任何建议。

3 个答案:

答案 0 :(得分:2)

感谢您的帮助,基于Agent_L的建议,这就是我提出的建议:

文字资源类型:

struct _resource {
    const char * content;      // File content
    size_t size;               // File size
    size_t ptrloc;             // 'Pointer' location
};
typedef struct _resource RES_TXT;

基于fread重新阅读:

size_t resread( void* buffer, size_t size, size_t count, RES_TXT * resource)
{
    size_t actualCount = ( resource->size - resource->ptrloc ) / size;
    actualCount = min( count, actualCount );
    if ( actualCount <= 0 ) return 0;
    memcpy(buffer, (resource->_ptr + resource->ptrloc), (actualCount * size) );
    resource->ptrloc += (actualCount * size);
    return actualCount;
}

并根据fseek完成resseek:

int resseek( RES_TXT * resource, long offset, int origin ) {
    size_t nextloc;
    switch ( origin ) {
        case SEEK_SET: nextloc = 0;
            break;
        case SEEK_CUR: nextloc = resource->ptrloc;
            break;
        case SEEK_END: nextloc = resource->size;
            break;
        default: return -1;
    }
    nextloc += offset;
    if ( nextloc >= 0  && nextloc < resource->size )
        resource->ptrloc = nextloc;
    else
        return -1;
    return 0;
}

现在可以替换对fseek和fread的任何调用以使用资源而不是外部文件。

答案 1 :(得分:1)

文件句柄不仅包含数据,还包含它的长度和当前位置。你必须复制它。 (handwirtten code,unproven):

struct resFile
{
    char* pData;
    int iLenght;
    int iCurrPosition;
};

size_t resread( void* buffer, size_t size, size_t count, resFile* resource)
{
    int ActualRead = min(size*count, resource->iLenght - resource->iCurrPosition);
    memcpy(buffer, resource->pData + resource->iCurrPosition, ActualRead);
    resource->iCurrPostion += ActualRead;
    return ActualRead;
}

答案 2 :(得分:0)

让我通知您fread改变当前文件位置。这意味着您不需要每次都调用fseek。从这个角度来看,可能,您可以通过简单地增加resseek指针来避免实现Buffer