0

我正在尝试获取一个 html 文件,它是位于 tar 文件中的文件之一,我有一些想法,我不知道它是否正确?如果我错了,请指出我。我的想法是——

我从 tar 文件中创建一个流并将该流存储在缓冲区中以便获得其内容,然后使用 strstr 命令搜索 tar 文件中的 html 文件(因为我知道在我的 tar 文件中,html 内容从“<!doctype html" 并以 <"/html>"结束,所以我将加载它们之间的内容,这实际上是 html 文件)。我的方法对吗??

问题是当我给缓冲区提供非常大的大小(但小于包含 html + 许多其他文件的 tar 文件的大小)时,它会在调试时产生堆栈溢出。但是当我给出小索引时,如果我在记事本中打开 tar 文件,它会显示位于启动中的其他文件的内容(我已经通过在记事本中打开 tar 文件进行检查,这些内容确实存在于 tar 文件中,但在开始时tar 文件,所以当我增加缓冲区的索引以访问位于文件中间的 html 文件(实际上需要非常大的索引)时,它会在调试时提供 stackoverflow)。我的代码是-

     HRESULT AMEPreviewHandler:: CreateHtmlPreview(IStream *m_pStream) //this function is called from
        // somewhere
             ULONG  CbRead;
                    const int Size= 115000 ; 
                    char Buffer[Size+1];
                    (m_pStream)->Read(Buffer, Size, &CbRead );
                    Buffer[CbRead ] = L'\0';
                    char *compare= "<!doctype html"; //this we have to search in tar file
    // content because the html file contents starts from here
                    char * StartPosition;
                    StartPosition = strstr (Buffer,compare); //StartPosition  gives Bad
// pointer when Size is small on debugging at this small size i can see some contents in buffer which i 
//can find in tar file at starting 
                    __int64 count=0; 
                    while (StartPosition!=NULL)
                    {
    MessageBox(m_hwndPreview,L"hurr inside the while loop",L"BTN WND",MB_ICONINFORMATION);

                        count=StartPosition-Buffer+1; //to get the location of 
    //"<!doctype html";

                                                        }


                    MessageBox(m_hwndPreview,L"wafter the while loop in CreateHtmlPreview  ",L"BTN WND",MB_ICONINFORMATION); 
                    return true;
                }

请告诉我获取tar文件中html文件内容的方法是否正确?为什么当我给缓冲区提供大索引以访问位于 tar 文件中间的缓冲区内容时,它会导致堆栈溢出?即使我声明的大小小于 tar 文件的大小,如果我手动查看?

4

1 回答 1

0

堆栈的大小有限,因此仅分配任意大的数量是行不通的——您要么需要对其设置一个适合可用堆栈的限制,然后循环读取(如果您的“针串”(你在找什么)跨越两个块之间的“间隙”,但有可能克服(见下文)。或者干脆不使用堆栈,而是使用new分配足够的内存来保存整个文件。当然,如果该文件非常大,无法正常工作-文件可能大于计算机的总内存,然后您就被塞满了,并且不得不返回“一次读取一点”。这在术语上也很浪费将整个文件读入内存的资源,只是将大部分文件扔掉。

使用一个缓冲区的一种解决方案是将“针”的长度添加到缓冲区的大小。当你第二次读取时,从缓冲区的后面复制长度的needle字节到开头,然后读入缓冲区的“needle”字节中,然后从缓冲区的开头开始搜索。只要缓冲区与“针”相比相当大,两次搜索缓冲区的同一部分的开销就无关紧要了。

于 2013-07-24T09:23:17.363 回答