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

Resource instead of external file C++

本文关键字:文件 C++ 外部 资源      更新时间:2023-10-16

我正在重用一些旧代码(最初是在c上开发的,而不是c ++)和一些函数来打开/读取/操作文本文件。文本文件的路径作为字符串 (char*) 传递给函数,然后使用以下方法打开: FileToUse = fopen(filename, "rb");然后使用对fread()fseek()的多次调用。已知此代码适用于外部文本文件,但现在我想将文本文件作为资源包含在我的项目(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 移动,我想知道我使用临时指针的方法是否正确。

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

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

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

任何建议都非常感谢。

感谢您的帮助,根据Agent_L的建议,这就是我想出的:

文本资源类型:

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

基于恐惧的重读:

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 的重新搜索:

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 的任何调用,以使用资源而不是外部文件。

文件句柄不仅包含数据,还包含其长度和当前位置。你必须复制它。(手工代码,未经验证):

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;
}

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