Mar*_*ark 4 vb.net httpwebresponse dotnetzip
尽管找到了例子,但我在这方面遇到了一些麻烦。我认为这可能是一个编码问题,但我不确定。我正在尝试以编程方式从使用 cookie 的 https 服务器下载文件(因此我使用 httpwebrequest)。我正在调试打印要检查的流的容量,但输出[原始]文件看起来不同。尝试过其他编码方式均无效。
代码:
    Sub downloadzip(strURL As String, strDestDir As String)
    Dim request As HttpWebRequest
    Dim response As HttpWebResponse
    request = Net.HttpWebRequest.Create(strURL)
    request.UserAgent = strUserAgent
    request.Method = "GET"
    request.CookieContainer = cookieJar
    response = request.GetResponse()
    If response.ContentType = "application/zip" Then
        Debug.WriteLine("Is Zip")
    Else
        Debug.WriteLine("Is NOT Zip: is " + response.ContentType.ToString)
        Exit Sub
    End If
    Dim intLen As Int64 = response.ContentLength
    Debug.WriteLine("response length: " + intLen.ToString)
    Using srStreamRemote As StreamReader = New StreamReader(response.GetResponseStream(), Encoding.Default)
        'Using ms As New MemoryStream(intLen)
        Dim fullfile As String = srStreamRemote.ReadToEnd
        Dim memstream As MemoryStream = New MemoryStream(New UnicodeEncoding().GetBytes(fullfile))
        'test write out to flie
        Dim data As Byte() = memstream.ToArray()
        Using filestrm As FileStream = New FileStream("c:\temp\debug.zip", FileMode.Create)
            filestrm.Write(data, 0, data.Length)
        End Using
        Debug.WriteLine("Memstream capacity " + memstream.Capacity.ToString)
        'Dim strData As String = srStreamRemote.ReadToEnd
        memstream.Seek(0, 0)
        Dim buffer As Byte() = New Byte(2048) {}
        Using zip As New ZipInputStream(memstream)
            Debug.WriteLine("zip stream cap " + zip.Length.ToString)
            zip.Seek(0, 0)
            Dim e As ZipEntry
            Dim flag As Boolean = True
            Do While flag ' daft, but won't assign e=zip... tries to evaluate
                e = zip.GetNextEntry
                If IsNothing(e) Then
                    flag = False
                    Exit Do
                Else
                    e.UseUnicodeAsNecessary = True
                End If
                If Not e.IsDirectory Then
                    Debug.WriteLine("Writing out " + e.FileName)
                    '    e.Extract(strDestDir)
                    Using output As FileStream = File.Open(Path.Combine(strDestDir, e.FileName), _
                                                          FileMode.Create, FileAccess.ReadWrite)
                        Dim n As Integer
                        Do While (n = zip.Read(buffer, 0, buffer.Length) > 0)
                            output.Write(buffer, 0, n)
                        Loop
                    End Using
                End If
            Loop
        End Using
        'End Using
    End Using 'srStreamRemote.Close()
    response.Close()
End Sub
因此,我下载了正确大小的文件,但 dotnetzip 无法识别它,并且复制出来的文件是不完整/无效的 zip。我今天大部分时间都花在这上面了,准备放弃了。
我认为答案是分解问题,也许改变代码中的几个方面。
例如,让我们摆脱将响应流转换为字符串的情况:
Dim memStream As MemoryStream
Using rdr As System.IO.Stream = response.GetResponseStream
    Dim count = Convert.ToInt32(response.ContentLength)
    Dim buffer = New Byte(count) {}
    Dim bytesRead As Integer
    Do
        bytesRead += rdr.Read(buffer, bytesRead, count - bytesRead)
    Loop Until bytesRead = count
    rdr.Close()
    memStream = New MemoryStream(buffer)
End Using
接下来,有一种更简单的方法将内存流的内容输出到文件。考虑你的代码
Dim data As Byte() = memstream.ToArray()
Using filestrm As FileStream = New FileStream("c:\temp\debug.zip", FileMode.Create)
    filestrm.Write(data, 0, data.Length)
End Using
可以替换为
Using filestrm As FileStream = New FileStream("c:\temp\debug.zip", FileMode.Create)
    memstream.WriteTo(filestrm)
End Using
这消除了将内存流传输到另一个字节数组,然后将字节数组推送到流中的需要,而实际上内存流可以将数据直接传输到文件(通过文件流)保存中间人缓冲区。
我承认我没有使用过您正在使用的 Zip/压缩库,但是通过上述修改,您已经删除了流、字节数组、字符串等之间不必要的传输,并希望消除了您遇到的编码问题。
尝试一下,让我们知道您的进展如何。考虑尝试打开您保存的文件(“C:\temp\debug.zip”)以查看它是否被列为损坏。如果没有,那么您至少知道代码中的内容是可以正常工作的。