我有一個包含“http://whatever.pdf”形式的字串的 PDF 字串串列,需要創建它們的 zip 檔案并將其作為下載流式傳輸到客戶端。
奇怪的是,如果我創建 zip(我正在使用 ZipOutputStream)并將檔案寫入磁盤它可以作業,我可以打開生成的 zip 檔案并毫無問題地解壓縮它,但是如果我流式傳輸它(我的需要做)我得到一個相同大小的 zip 檔案,但在嘗試打開它時出錯。
創建郵編:
Private Function CreateZip(pdfPathList As List(Of String), fileRoot As String) As String
Response.Clear()
Response.BufferOutput = False
Response.ContentType = "application/zip"
Response.AddHeader("content-disposition", "attachment; filename=pdf.zip")
Dim pdfPathListLocal As List(Of String) = Utility.DownloadFilesFromList(pdfPathList, fileRoot)
Dim outputMemStream = Utility.GenerateZipOutpuStream(pdfPathListLocal)
Dim zipName As String = Guid.NewGuid.ToString() & ".zip"
outputMemStream.Position = 0
'Utility.WriteMemoryStreamToDisk(outputMemStream, fileRoot & "\" & zipName) => This line creates a valid zip file on disk, but I need to avoid it.
Response.AddHeader("Content-Length", outputMemStream.Length)
Response.Write(outputMemStream) => Writes the file ok in downloads, but apparently corrupted.
Return zipName
End Function
從串列下載檔案:
Public Shared Function DownloadFilesFromList(pdfPathList As List(Of String), fileRoot As String) As List(Of String)
Dim pdfPathListLocal As New List(Of String)
Dim Client As WebClient = New WebClient()
For Each strFile In pdfPathList
Dim sFile As String = Path.GetFileName(strFile)
Dim localFile As String = fileRoot "\" sFile
Client.DownloadFile(strFile, localFile)
pdfPathListLocal.Add(localFile)
Next
Return pdfPathListLocal
End Function
生成ZipOutpuStream:
Public Shared Function GenerateZipOutpuStream(pdfPathListLocal As List(Of String)) As MemoryStream
Dim outputMemStream = New MemoryStream()
Dim strmZipOutputStream = New ZipOutputStream(outputMemStream)
strmZipOutputStream.SetLevel(9)
Dim objCrc32 As New Crc32()
For Each strFile In pdfPathListLocal
Dim strmFile As FileStream = IO.File.OpenRead(strFile)
Dim abyBuffer(Convert.ToInt32(strmFile.Length - 1)) As Byte
strmFile.Read(abyBuffer, 0, abyBuffer.Length)
Dim sFile As String = Path.GetFileName(strFile)
Dim theEntry As ZipEntry = New ZipEntry(sFile)
theEntry.DateTime = DateTime.Now
theEntry.Size = strmFile.Length
strmFile.Close()
objCrc32.Reset()
objCrc32.Update(abyBuffer)
theEntry.Crc = objCrc32.Value
strmZipOutputStream.PutNextEntry(theEntry)
strmZipOutputStream.Write(abyBuffer, 0, abyBuffer.Length)
'IO.File.Delete(strFile)
Next
strmZipOutputStream.Finish()
Return outputMemStream
End Function
寫入記憶體流到磁盤:
Public Shared Sub WriteMemoryStreamToDisk(outputMemStream As MemoryStream, file As String)
Dim buffer As Byte() = outputMemStream.ToArray()
Dim ms As New MemoryStream(buffer)
Dim newFile As New FileStream(file, FileMode.Create, FileAccess.Write)
ms.WriteTo(newFile)
newFile.Close()
ms.Close()
End Sub
可能有什么問題?有什么幫助嗎?
uj5u.com熱心網友回復:
在這種情況下,我總是首先做的是在文本查看器中打開“損壞的”檔案,然后弄清楚所謂的(檔案型別)檔案是否實際上是(檔案型別)檔案。事實證明,事實并非如此。例如,查看常規 ZIP 存檔時,前 2 個字符必須是“PK”,檔案的其余部分是二進制“亂碼”。與 PDF 類似:前幾個字符是“%PDF- (PDF 版本) ”,例如“%PDF-1.7”。
尤其是下載時,您可能會得到與預期不同的結果,例如右鍵單擊檔案鏈接 ->“另存為”。事實證明,它不是指向檔案的直接鏈接,而是某種將實際檔案推送到客戶端的腳本。當您“另存為”該鏈接時,您得到的是腳本的 HTML 輸出,而不是檔案本身。
還有很多反惡意軟體軟體可以監控網路流量并用其他東西替換可疑檔案。
你可能已經“淪為獵物”了。
uj5u.com熱心網友回復:
好的,因為我終于找到了問題的根源,我會回答自己,我希望對面臨同樣問題的其他人有所幫助。
問題在于 aspx“UpdatePanel”的作業方式,它執行部分回發,這與 con Response 物件不兼容并阻止其正常作業。
解決方案是禁用導致問題的特定元素的部分回發,在我的情況下:
添加這將導致一個DownloadPdfs 鏈接進行完整的回發,并且所有回應物件方法都將按預期作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/368461.html
