Program I am working on corrupts Excel files when it uploads them.
The file is ok on the local computer, but on the remote computer the file says corrupted when opening in Excel. Excel is able to repair the file, but I wan't to avoid the problem.
I don't seem to have any problems with image files so far.
Public Function UploadFile(ByVal User As String, ByVal oFile As FileInfo) As Boolean
Dim ftpRequest As FtpWebRequest
Dim ftpResponse As FtpWebResponse
Try
FtpCheckAndCreateDir(User)
ftpRequest = CType(FtpWebRequest.Create(Base + User + "/" + oFile.Name), FtpWebRequest)
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile
ftpRequest.Proxy = Nothing
ftpRequest.UseBinary = True
ftpRequest.Credentials = Cred ' New NetworkCredential(...)
ftpRequest.KeepAlive = KeepAlive ' false
ftpRequest.EnableSsl = UseSSL ' false
If UseSSL Then ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf ValidateServerCertificate)
Dim fileContents(oFile.Length) As Byte
Using fr As FileStream = oFile.OpenRead
fr.Read(fileContents, 0, Convert.ToInt32(oFile.Length))
End Using
Using writer As Stream = ftpRequest.GetRequestStream
writer.Write(fileContents, 0, fileContents.Length)
End Using
ftpResponse = CType(ftpRequest.GetResponse, FtpWebResponse)
ftpResponse.Close()
ftpRequest = Nothing
Return True
Catch ex As WebException
Return False
End Try
End Function
EDIT:
So I took a file and uploaded it through coffeecup free ftp, downloaded it, and it opened fine.
I used my program to upload the file, and then downloaded it with with coffeecup and it came up as damaged when I tried to open it in excel.
I used HxD to compare the files, and it came back with a message saying: "The chosen files are identical. The files sizes are different, though!" and when I run a checksum on both files they come back with different values.
I'm not really sure how to troubleshoot this or what I can research to find the answer.
I can provide the files if needed.
So, after a lot of searching and looking, I found this answer: C# - File is corrupt after uploaded to server
which I was able to use to get a file to upload without being corrupted.
The final ftp function with old parts commented out to make it easier to see the changes:
Public Function UploadFile(ByVal User As String, ByVal oFile As FileInfo) As Boolean
Dim ftpRequest As FtpWebRequest
Dim ftpResponse As FtpWebResponse
Try
FtpCheckAndCreateDir(User)
ftpRequest = CType(FtpWebRequest.Create(Base + User + "/" + oFile.Name), FtpWebRequest)
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile
ftpRequest.Proxy = Nothing
ftpRequest.UseBinary = True
ftpRequest.Credentials = Cred
ftpRequest.KeepAlive = KeepAlive
ftpRequest.EnableSsl = UseSSL
If UseSSL Then ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf ValidateServerCertificate)
Dim fileContents(oFile.Length) As Byte
Using fr As FileStream = oFile.OpenRead
Using writer As Stream = ftpRequest.GetRequestStream
fr.CopyTo(writer) ' This is the important part.
'writer.Write(fileContents, 0, fileContents.Length)
End Using
'fr.Read(fileContents, 0, Convert.ToInt32(oFile.Length))
End Using
'Using writer As Stream = ftpRequest.GetRequestStream
' writer.Write(fileContents, 0, fileContents.Length)
'End Using
ftpResponse = CType(ftpRequest.GetResponse, FtpWebResponse)
ftpResponse.Close()
ftpRequest = Nothing
Return True
Catch ex As WebException
Return False
End Try
End Function
The issue is your file writer, it is important to note that images are very forgiving when missing information.
I hope this FTP class will help you get on the right path:
Public Class FTP
'-------------------------[BroCode]--------------------------
'----------------------------FTP-----------------------------
Private _credentials As System.Net.NetworkCredential
Sub New(ByVal _FTPUser As String, ByVal _FTPPass As String)
setCredentials(_FTPUser, _FTPPass)
End Sub
Public Sub UploadFile(ByVal _FileName As String, ByVal _UploadPath As String)
Dim _FileInfo As New System.IO.FileInfo(_FileName)
Dim _FtpWebRequest As System.Net.FtpWebRequest = CType(System.Net.FtpWebRequest.Create(New Uri(_UploadPath)), System.Net.FtpWebRequest)
_FtpWebRequest.Credentials = _credentials
_FtpWebRequest.KeepAlive = False
_FtpWebRequest.Timeout = 20000
_FtpWebRequest.Method = System.Net.WebRequestMethods.Ftp.UploadFile
_FtpWebRequest.UseBinary = True
_FtpWebRequest.ContentLength = _FileInfo.Length
Dim buffLength As Integer = 2048
Dim buff(buffLength - 1) As Byte
Dim _FileStream As System.IO.FileStream = _FileInfo.OpenRead()
Try
Dim _Stream As System.IO.Stream = _FtpWebRequest.GetRequestStream()
Dim contentLen As Integer = _FileStream.Read(buff, 0, buffLength)
Do While contentLen <> 0
_Stream.Write(buff, 0, contentLen)
contentLen = _FileStream.Read(buff, 0, buffLength)
Loop
_Stream.Close()
_Stream.Dispose()
_FileStream.Close()
_FileStream.Dispose()
Catch ex As Exception
MessageBox.Show(ex.Message, "Upload Error: ", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Public Sub DownloadFile(ByVal _FileName As String, ByVal _ftpDownloadPath As String)
Try
Dim _request As System.Net.FtpWebRequest = System.Net.WebRequest.Create(_ftpDownloadPath)
_request.KeepAlive = False
_request.Method = System.Net.WebRequestMethods.Ftp.DownloadFile
_request.Credentials = _credentials
Dim _response As System.Net.FtpWebResponse = _request.GetResponse()
Dim responseStream As System.IO.Stream = _response.GetResponseStream()
Dim fs As New System.IO.FileStream(_FileName, System.IO.FileMode.Create)
responseStream.CopyTo(fs)
responseStream.Close()
_response.Close()
Catch ex As Exception
MessageBox.Show(ex.Message, "Download Error: ", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Public Function GetDirectory(ByVal _ftpPath As String) As List(Of String)
Dim ret As New List(Of String)
Try
Dim _request As System.Net.FtpWebRequest = System.Net.WebRequest.Create(_ftpPath)
_request.KeepAlive = False
_request.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails
_request.Credentials = _credentials
Dim _response As System.Net.FtpWebResponse = _request.GetResponse()
Dim responseStream As System.IO.Stream = _response.GetResponseStream()
Dim _reader As System.IO.StreamReader = New System.IO.StreamReader(responseStream)
Dim FileData As String = _reader.ReadToEnd
Dim Lines() As String = FileData.Split(New String() {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
For Each l As String In Lines
ret.Add(l)
Next
_reader.Close()
_response.Close()
Catch ex As Exception
MessageBox.Show(ex.Message, "Directory Fetch Error: ", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Return ret
End Function
Private Sub setCredentials(ByVal _FTPUser As String, ByVal _FTPPass As String)
_credentials = New System.Net.NetworkCredential(_FTPUser, _FTPPass)
End Sub
End Class