我有一些舊代碼將二進制資料寫入 Response 物件的 BinaryWrite() 方法(經典 ASP)。它將 4MB 塊中的資料發送到 BinaryWrite(),但現在我想知道這是否有效,以及 BinaryWrite() 是否甚至被設計為處理串行資料塊(或者它是否應該只被呼叫,最多,每次頁面請求)。
我發現這個鏈接描述了“回應緩沖限制”應該如何增加,增加它似乎解決了我看到的問題(根本不使用我的分塊代碼)。 https://docs.microsoft.com/en-us/troubleshoot/iis/http-500-response-binarywrite
這是有問題的舊代碼:
HRESULT STDMETHODCALLTYPE CQVMActiveHost::WriteData (const VOID* pcvData, DWORD cbData, __out DWORD* pcbWritten)
{
HRESULT hr;
DISPPARAMS dispParams = {0};
VARIANT vWrite = {0}, vResult = {0};
Check(LoadResponseObject());
dispParams.cArgs = 1;
dispParams.rgvarg = &vWrite;
if(m_fSupportsBinary)
{
SAFEARRAYBOUND Bound;
DWORD cbRemaining = cbData;
Bound.lLbound = 0;
vWrite.vt = VT_ARRAY | VT_UI1;
while(0 < cbRemaining)
{
PVOID pbPtr;
Bound.cElements = min(cbRemaining, 4 * 1024 * 1024);
vWrite.parray = SafeArrayCreate(VT_UI1, 1, &Bound);
CheckAlloc(vWrite.parray);
SafeArrayAccessData(vWrite.parray, &pbPtr);
CopyMemory(pbPtr, pcvData, Bound.cElements);
SafeArrayUnaccessData(vWrite.parray);
VariantClear(&vResult);
Check(m_pResponse->Invoke(m_dispidBinaryWrite, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispParams, &vResult, NULL, NULL));
SafeArrayDestroy(vWrite.parray);
vWrite.parray = NULL;
pcvData = reinterpret_cast<const BYTE*>(pcvData) Bound.cElements;
cbRemaining -= Bound.cElements;
}
vWrite.vt = VT_EMPTY;
}
else
I've seen a couple different behaviors with the old code. In some tests, the first call to BinaryWrite() succeeded, but subsequent calls failed with the "exception occurred" HRESULT. In other tests, the calls seemed to succeed, but the browser didn't receive any data.
Are there any scenarios where it would make sense to make multiple calls to BinaryWrite() with chunked data?
Or should I always increase the "Response Buffering Limit" value to more than 4MB and just make a single call to BinaryWrite() with the full data?
Thanks!
uj5u.com熱心網友回復:
我不得不懷疑該Response.Buffer屬性是否是false我最初撰寫上述代碼時的屬性。我發現的是以下內容:
Response.BinaryWrite()每個頁面請求可以多次呼叫該方法。- 如果要向客戶端回傳大量資料,則將資料拆分為多次呼叫
Response.BinaryWrite(). - 默認情況下,IIS(對于 ASP)中的“回應緩沖限制”值為 4MB。
- 如果
Response.Buffer是true,則Response.BinaryWrite()可能會多次呼叫 ,直到總資料達到“回應緩沖限制”值。在這一點上,Response.Flush()必須被呼叫。否則,嘗試發送更多資料會導致錯誤 0x80020009。 - 如果
Response.Buffer是false,則不要呼叫Response.Flush(),而是將資料拆分為多個(較小的)呼叫Response.BinaryWrite()。 - 例如,我試圖通過多次呼叫發送一個 12MB 的檔案
Response.BinaryWrite(),每個塊為 4MB。啟用了緩沖,因此第一次呼叫成功,但下一次呼叫失敗。將“回應緩沖限制”提高到 16MB“解決”了這個問題,但增加了 ASP 的緩沖分配。
最終,我修改了我的分塊代碼以首先查詢Response.Buffer屬性。資料總是以較小的片段發送到Response.BinaryWrite(),但Response.Flush()如果啟用緩沖也會被呼叫。
最后,不要設定Content-Length標題。瀏覽器可能不知道將下載多少位元組,但它會正確接收檔案而無需手動設定該標頭。設定該標題會中斷下載。
最后的 ASP 腳本:
function GoDownloadFile (strPath)
{
var idxName = strrchr(strPath, '/');
var strFolder = left(strPath, idxName 1);
var strFile = right(strPath, len(strPath) - (idxName 1));
var oFS = Security.GetChannel().OpenFileSystem();
oFS.Folder = strFolder;
Response.ContentType = Host.GetContentType(strFile);
Response.AddHeader("Content-Disposition", "attachment; FileName=\"" strFile "\"");
Host.BinaryWrite(oFS.ReadFile(strFile));
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/359971.html
標籤:winapi iis visual-c asp-classic
