Why is my online text file downloading blank in VB

2020-05-09 00:27发布

问题:

I'm having trouble downloading a text file in Visual Studio Community 2015. It's a text file in my OneDrive Public folder containing the version number of my application (1.0.0.0). The download link I use works perfectly when opened manually, but when my VB code executes, it does download the text file correctly but the file is blank when I open it and I cannot figure out where it's going wrong.

In Module1, I have a sub for downloading and a sub for reading the file afterwards:

Module Module1

    ' Public variables

    Public tempPath As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) & "\Temp"

    Sub DownloadToTemp(filePath As String)
        ' Download a text file, ready to read contents

        If Not IO.Directory.Exists(tempPath & "\Temp") Then
            IO.Directory.CreateDirectory(tempPath & "\Temp")
        End If

        Try
            My.Computer.Network.DownloadFile _
                (address:=filePath,
                destinationFileName:=tempPath & "\TempText.txt",
                userName:=String.Empty,
                password:=String.Empty,
                showUI:=False,
                connectionTimeout:=10000,
                overwrite:=True)

        Catch ex As Exception
            MsgBox("Can't read file" & vbCrLf & ex.Message)
        End Try

    End Sub

    Sub ReadFile()

        Dim fStream As New IO.FileStream(tempPath & "\TempText.txt", IO.FileMode.Open)
        Dim sReader As New System.IO.StreamReader(fStream)
        Dim sArray As String() = Nothing
        Dim index As Integer = 0

        Do While sReader.Peek >= 0
            ReDim Preserve sArray(index)
            sArray(index) = sReader.ReadLine
            index += 1
        Loop

        fStream.Close()
        sReader.Close()

        ' Test
        Dim fileContents As String = Nothing
        If sArray Is Nothing Then
            MsgBox("No Data Found")
            Exit Sub
        End If
        For index = 0 To UBound(sArray)
            fileContents = fileContents & sArray(index) & vbCrLf
        Next

        MessageBox.Show(fileContents)

    End Sub

End Module

And they're called from the main code:

    Private Sub frmSplash_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    lblVersion.Text = "v" & Application.ProductVersion

    ' Check available version online

    Call DownloadToTemp("https://onedrive.live.com/download?resid=DE2331D1649390C1!16974&authkey=!AH2cr1S1SHs9Epk&ithint=file%2ctxt")
    Call ReadFile()

End Sub

So, everything seems to be correct and working, no errors or exceptions, but the file that my VB code downloads is blank, but manually clicking the download link from the code downloads it with the contents intact. Can anybody see why this would be happening?

回答1:

The code will download whatever is in that location, but the link appears to redirect you to another place. It downloads the response it gets from the link, which is nothing since there is nothing there.

You need a direct link to the file for it to work properly. Try this instead:

DownloadToTemp("https://gwhcha-dm2306.files.1drv.com/y4mwlpYyvyCFDPp3NyPM6WqOz8-Ocfn-W0_4RbdQBtNMATYn2jNgWMRgpl_gXdTBteipIevz07_oUjCkeNoJGUxNO9jC9IdXz60NNEvzx2cU9fYJU_oRgqBFyA8KkBs8VGc8gDbs2xz7d3FyFnkgRfq77A2guoosQkO4pVMDiEYRoJRCWOtQk2etsMXyT8nSEnPoGV6ZG0JWc6qt55Mhi_zeA/Hotshot_Version.txt?download&psid=1")

Also, you don't need to use the Call keyword. It exists only for backwards compatibility with VB6 and older versions.


EDIT:

Here's an example of downloading a file using the HttpWebRequest class. By setting its AllowAutoRedirect and MaximumAutomaticRedirections properties you allow it to be redirected before it attempts to download the file.

''' <summary>
''' Downloads a file from an URL and allows the page to redirect you.
''' </summary>
''' <param name="Url">The URL to the file to download.</param>
''' <param name="TargetPath">The path and file name to download the file to.</param>
''' <param name="AllowedRedirections">The maximum allowed amount of redirections (default = 32).</param>
''' <param name="DownloadBufferSize">The amount of bytes of the download buffer (default = 4096 = 4 KB).</param>
''' <remarks></remarks>
Private Sub DownloadFileWithRedirect(ByVal Url As String, _
                                     ByVal TargetPath As String, _
                                     Optional ByVal AllowedRedirections As Integer = 32, _
                                     Optional ByVal DownloadBufferSize As Integer = 4096)
    'Create the request.
    Dim Request As HttpWebRequest = DirectCast(WebRequest.Create(Url), HttpWebRequest)
    Request.Timeout = 10000 '10 second timeout.
    Request.MaximumAutomaticRedirections = AllowedRedirections
    Request.AllowAutoRedirect = True

    'Get the response from the server.
    Using Response As HttpWebResponse = DirectCast(Request.GetResponse(), HttpWebResponse)
        'Get the stream to read the response.
        Using ResponseStream As Stream = Response.GetResponseStream()

            'Declare a download buffer.
            Dim Buffer() As Byte = New Byte(DownloadBufferSize - 1) {}
            Dim ReadBytes As Integer = 0

            'Create the target file and open a file stream to it.
            Using TargetFileStream As New FileStream(TargetPath, FileMode.Create, FileAccess.Write, FileShare.None)

                'Start reading into the buffer.
                ReadBytes = ResponseStream.Read(Buffer, 0, Buffer.Length)

                'Loop while there's something to read.
                While ReadBytes > 0
                    'Write the read bytes to the file.
                    TargetFileStream.Write(Buffer, 0, ReadBytes)

                    'Read more into the buffer.
                    ReadBytes = ResponseStream.Read(Buffer, 0, Buffer.Length)
                End While

            End Using

        End Using
    End Using
End Sub

Example usage:

Try
    DownloadFileWithRedirect("https://onedrive.live.com/download?resid=DE2331D1649390C1!16974&authkey=!AH2cr1S1SHs9Epk&ithint=file%2ctxt", Path.Combine(tempPath, "TempText.txt"))
Catch ex As Exception
    MessageBox.Show("An error occurred:" & Environment.NewLine & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try