【问题标题】:Confused about stream buffers对流缓冲区感到困惑
【发布时间】:2012-06-22 08:18:41
【问题描述】:

我正在尝试熟悉网络编程,还有什么比设计 FTP 客户端代码库更好的起点?

到目前为止,我做得不是很好。我正在尝试创建一种将文件从远程服务器下载到本地文件路径的方法。为此,我能找到的所有示例都声明了一个用作数据缓冲区的字节数组。我完全理解这样做的意义,而不是按字节读取和写入字节,但我就是无法让它工作。每当我设置大于 1 字节的缓冲区时,输出都会以某种方式损坏(不同的校验和、媒体文件无法播放等)。

谁能指出我在这里做错了什么:

Public Function DownloadFile(source As Uri, output As Uri) As FtpStatusCode
    Dim request = FtpWebRequest.Create(source)
    request.Method = WebRequestMethods.Ftp.DownloadFile

    Using response As FtpWebResponse = CType(request.GetResponse, FtpWebResponse)
        Using outputStream = New FileStream(output.AbsolutePath, FileMode.Create)
            Do
                Dim buffer(8192) As Byte
                response.GetResponseStream.Read(buffer, 0, buffer.Length)
                outputStream.Write(buffer, 0, buffer.Length)
            Loop While outputStream.Position < response.ContentLength
        End Using
        Return response.StatusCode
    End Using
End Function

因为当我将缓冲区大小设置为 1 时,这段代码确实有效,所以我觉得字节顺序有问题。但是所有这些代码都是同步的,那怎么可能……

编辑

我现在可以使用它了,所以这是代码解决方案以供将来参考(再次感谢@tcarvin):

Public Function DownloadFile(source As Uri, output As Uri) As FtpStatusCode
    Dim request = FtpWebRequest.Create(source)
    request.Method = WebRequestMethods.Ftp.DownloadFile

    Using response As FtpWebResponse = CType(request.GetResponse, FtpWebResponse)
        Using inputStream = response.GetResponseStream
            Using outputStream = New FileStream(output.AbsolutePath, FileMode.Create)
                Do
                    Dim buffer(8192) As Byte
                    Dim buffered = inputStream.Read(buffer, 0, buffer.Length).Read(buffer, 0, buffer.Length)
                    outputStream.Write(buffer, 0, buffered)
                Loop While outputStream.Position < response.ContentLength
            End Using
        End Using
        Return response.StatusCode
    End Using
End Function

【问题讨论】:

    标签: vb.net ftp stream buffer


    【解决方案1】:

    从流中读取时,需要捕获方法的返回值。读取返回刚刚读取的字节数。这是您需要写入输出流的字节数。

    【讨论】:

    • 啊,确实有道理。看看这次我能走多远。
    • 我还建议调用一次 GetResponseStream() 并将其分配给一个变量,然后在该实例上调用 Read()。完成后也必须关闭/处理流。
    • 我的印象是处理 webresponse 实例也会处理响应流。无论如何,我确实通过将 buffer.Length 替换为缓冲区中的实际可用字节数来实现它。
    • 啊,我只是看了看,至少对于 4.0 及更高版本,这似乎是正确的(如果需要,响应将处理流)。两者都处理不会有任何害处,但我想不需要。
    猜你喜欢
    • 2012-09-24
    • 2020-07-09
    • 1970-01-01
    • 2019-01-15
    • 2016-03-14
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多