Reputation: 14113
I'm trying to familiarize myself with network programming, and what better place to start than designing an FTP client code library?
So far I'm not doing very good. I'm trying to create a method which downloads a file from a remote server to a local file path. To do so, all the examples that I could find declare a byte array that serves as a data buffer. I completely understand the point of doing that, rather than reading and writing byte per byte, but I just can't get it to work. Whenever I set a buffer greater than 1 byte, the output is somehow corrupted (different checksums, media files won't play etc).
Can someone please point out what I'm doing wrong here:
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
Because this code does work when I set the buffer size to 1, I feel like there's something going wrong with the byte order. But all of this code is synchronous, so how is that even possible...
EDIT
I got it to work now, so here's the code solution for future reference (thanks again @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
Upvotes: 0
Views: 1588
Reputation: 10855
When reading from a stream, you need to capture the return value of the method. Read returns how many bytes were just read. That is the number of bytes you need to then write to your output stream.
Upvotes: 1