VB.NET FTP Downloaded file corrupt - vb.net

I want to download all file that located on FTP site. I break into 2 operations. First is to get the list of all files in the directory. Then I proceed to second which download each file. But unfortunately, the downloaded file is corrupt. Worst over, it affect the file on FTP folder. Both folder contains corrupt file. From a viewing thumbnails image to default image thumbnails. How this happen and to overcome this? Below are my code; full code class. I provide as reference and guide to do a correct way :)
Private strTargetPath As String
Private strDestPath As String
Private Sub frmLoader_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
objSQL = New clsSQL
If objSQL.SQLGetAllData Then 'Get data from SQL and insert into an arraylist
strTargetPath = "ftp://192.168.1.120/image/"
strDestPath = "D:\Application\FTPImg\"
ListFileFromFTP()
End If
Catch ex As Exception
strErrMsg = "Oops! Something is wrong with loading login form."
MessageBox.Show(strErrMsg & vbCrLf & "ExMsg: " & ex.Message, "Error message!", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Sub ListFileFromFTP()
Dim arrFile As ArrayList
Dim strPath As String
Try
Dim reqFTP As FtpWebRequest
reqFTP = FtpWebRequest.Create(New Uri(strTargetPath))
reqFTP.UseBinary = True
reqFTP.Credentials = New NetworkCredential("user", "user123")
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory
reqFTP.Proxy = Nothing
reqFTP.KeepAlive = False
reqFTP.UsePassive = False
Dim response As FtpWebResponse = DirectCast(reqFTP.GetResponse(), FtpWebResponse)
Dim sr As StreamReader
sr = New StreamReader(reqFTP.GetResponse().GetResponseStream())
Dim FileListing As String = sr.ReadLine
arrFile = New ArrayList
While FileListing <> Nothing
strPath = strTargetPath & FileListing
arrFile.Add(strPath)
FileListing = sr.ReadLine
End While
sr.Close()
sr = Nothing
reqFTP = Nothing
response.Close()
For i = 0 To (arrFile.Count - 1)
DownloadImage(arrFile.Item(i))
Next
Catch ex As Exception
strErrMsg = "Oops! Something is wrong with ListFileFromFTP."
MessageBox.Show(strErrMsg & vbCrLf & "ExMsg: " & ex.Message, "Error message!", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Public Function DownloadImage(ByVal strName As String) As String
Dim ftp_request As FtpWebRequest = Nothing
Dim ftpStream As Stream = Nothing
Dim strOldName As String
Dim strNewName As String
Dim withoutextension As String
Dim extension As String
Try
strOldName = strTargetPath & strName
withoutextension = Path.GetFileNameWithoutExtension(strOldName)
extension = Path.GetExtension(strOldName)
strNewName = strDestPath & withoutextension & extension
ftp_request = CType(System.Net.FtpWebRequest.Create(strName), System.Net.FtpWebRequest)
ftp_request.Method = System.Net.WebRequestMethods.Ftp.UploadFile
ftp_request.Credentials = New System.Net.NetworkCredential("user", "user123")
ftp_request.UseBinary = True
ftp_request.KeepAlive = False
ftp_request.Proxy = Nothing
Dim response As FtpWebResponse = DirectCast(ftp_request.GetResponse(), FtpWebResponse)
Dim responseStream As IO.Stream = response.GetResponseStream
Dim fs As New IO.FileStream(strNewName, IO.FileMode.Create)
Dim buffer(2047) As Byte
Dim read As Integer = 0
Do
read = responseStream.Read(buffer, 0, buffer.Length)
fs.Write(buffer, 0, read)
Loop Until read = 0
responseStream.Close()
fs.Flush()
fs.Close()
responseStream.Close()
response.Close()
Catch ex As WebException
Dim response As FtpWebResponse = ex.Response
If response.StatusCode = FtpStatusCode.ActionNotTakenFileUnavailable Then
MsgBox(response.StatusDescription)
Return String.Empty
Else
MsgBox(response.StatusDescription)
End If
End Try
End Function
For download file, this is the right code that succeed:
Private Sub Download(ByVal strFTPPath As String)
Dim reqFTP As FtpWebRequest = Nothing
Dim ftpStream As Stream = Nothing
Try
Dim outputStream As New FileStream(strDestPath & strImgName, FileMode.Create)
reqFTP = DirectCast(FtpWebRequest.Create(New Uri(strFTPPath)), FtpWebRequest)
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile
reqFTP.UseBinary = True
reqFTP.Credentials = New NetworkCredential("user", "user123")
Dim response As FtpWebResponse = DirectCast(reqFTP.GetResponse(), FtpWebResponse)
ftpStream = response.GetResponseStream()
Dim cl As Long = response.ContentLength
Dim bufferSize As Integer = 2048
Dim readCount As Integer
Dim buffer As Byte() = New Byte(bufferSize - 1) {}
readCount = ftpStream.Read(buffer, 0, bufferSize)
While readCount > 0
outputStream.Write(buffer, 0, readCount)
readCount = ftpStream.Read(buffer, 0, bufferSize)
End While
ftpStream.Close()
outputStream.Close()
response.Close()
Catch ex As Exception
If ftpStream IsNot Nothing Then
ftpStream.Close()
ftpStream.Dispose()
End If
Throw New Exception(ex.Message.ToString())
End Try
End Sub

There is something strange in your code. You are closing the responseStream twice.
And you are using ftp request method uploadFile. But then downloading it.
Instead of using the ftp stuff use this instead. Its much more simple and your outsourcing the buffers and streams to microsoft, which should be less buggy than us.
Dim webClient = new WebClient()
webClient.Credentials = new NetworkCredential("user", "user123")
dim response = webClient.UploadFile("ftp://MyFtpAddress","c:\myfile.jpg")
dim sResponse = System.Text.Encoding.Default.GetString(response)

Related

Google Drive API v3 VB.NET Upload To Spesific Folder

Please Help, i'm trying to upload file to specific folder in my google drive using Vb.net. but, i'm googling for hours and not get working code. i cant sleep because this. here is my code:
Private Sub UploadFile(FilePath As String)
Try
If Service.ApplicationName <> "Google Drive VB Dot Net" Then CreateService()
Dim TheFile As New File()
TheFile.Name = "Database Sekretariat.accdb"
TheFile.Description = "A test document"
'TheFile.MimeType = "text/plain"
TheFile.Parents(0) = "1uMeTMRtvhm5_98udPmV8kp19aGtrmeQj"
Dim ByteArray As Byte() = System.IO.File.ReadAllBytes(FilePath)
Dim Stream As New System.IO.MemoryStream(ByteArray)
Dim UploadRequest As FilesResource.CreateMediaUpload = Service.Files.Create(TheFile, Stream, TheFile.MimeType)
UploadRequest.Upload()
Dim file As File = UploadRequest.ResponseBody
MsgBox("Upload Selesai " & file.Name & "")
Catch ex As Exception
MsgBox("Upload Gagal")
End Try
End Sub
use it in the following way, it is functional
First, i look for the ID folder
Public Sub SearchFolder()
IDFolderSave = String.Empty 'Global Variable
Try
Dim findrequest As FilesResource.ListRequest = Service.Files.List
Dim listFolder As Data.FileList = findrequest.Execute
For Each item As File In listFolder.Files
If item.MimeType = "application/vnd.google-apps.folder" Then
If item.Name = "NameFolder" Then
IDFolderSave = item.Id.ToString
Exit For
End If
End If
Next
Catch ex As Exception
Throw ex
End Try
'MsgBox("Folder id: " + idFolder)
End Sub
Second, upload file
Public Sub UploadFileInFolder()
Dim FilePath As String = String.Empty
FilePath = "C:\Icons\Loadding.gif"
Dim plist As List(Of String) = New List(Of String)
SearchFolder()
plist.Add(IDFolderSave) 'Set parent folder
If (System.IO.File.Exists(FilePath)) Then
Dim fileMetadata = New File() With {
.Name = "Test",
.Parents = plist
}
Dim request As FilesResource.CreateMediaUpload
Using stream = New System.IO.FileStream(FilePath, System.IO.FileMode.Open)
request = Service.Files.Create(fileMetadata, stream, "application/octet-stream")
request.Fields = "id, parents"
request.Upload()
End Using
Dim file As File = request.ResponseBody
IDFileShared = file.Id
SharedFile()
MsgBox("File upload: " + file.Id)
Else
MsgBox("File does not exist: " + FilePath)
End If
End Sub
I hope it helps you

VB.net synchronisation Folder and file [duplicate]

I am trying to download multiple directories from FTP server to my local machine,
I have tried this,
Const localFile As String = "C:\Documents and Settings\cr\Desktop\T\New Folder\"
Const remoteFile As String = "textbox.Text"
Const host As String = "ftp://ftp.example.com"
Const username As String = "username"
Const password As String = "password"
For i1 = 0 To ListBox1.SelectedItems.Count - 1
Dim li As New ListViewItem
li = ListView1.Items.Add(ListBox1.SelectedItems(i1))
Dim URI1 As String = host + remoteFile & "/" & ListBox1.SelectedItems(i1)
Dim ftp1 As System.Net.FtpWebRequest = CType(FtpWebRequest.Create(URI1), FtpWebRequest)
ftp1.Credentials = New System.Net.NetworkCredential(username, password)
ftp1.KeepAlive = False
ftp1.UseBinary = True
ftp1.Method = System.Net.WebRequestMethods.Ftp.DownloadFile
Using response As System.Net.FtpWebResponse = CType(ftp1.GetResponse, System.Net.FtpWebResponse)
Using responseStream As IO.Stream = response.GetResponseStream
Dim length As Integer = response.ContentLength
Dim bytes(length) As Byte
'loop to read & write to file
Using fs As New IO.FileStream(localFile & ListBox1.SelectedItems(i1), IO.FileMode.Create)
Dim buffer(2047) As Byte
Dim read As Integer = 1
Do
read = responseStream.Read(buffer, 0, buffer.Length)
fs.Write(buffer, 0, read)
Loop Until read = 0 'see Note(1)
responseStream.Close()
fs.Flush()
fs.Close()
End Using
responseStream.Close()
End Using
response.Close()
End Using
li.BackColor = Color.Aquamarine
Next
But here the problem is that I am able to download multiple files from folders, but unable to download the sub directories and their contents from the main directory.
Basically the main directory consist of files and sub directories both. So is there any possible way to download sub directory and its contents from FTP?
Thanks in advance.
Translating my answer to C# Download all files and subdirectories through FTP to VB.NET:
The FtpWebRequest does not have any explicit support for recursive file download (or any other recursive operation). You have to implement the recursion yourself:
List the remote directory
Iterate the entries, downloading files and recursing into subdirectories (listing them again, etc.)
A tricky part is to identify files from subdirectories. There's no way to do that in a portable way with the FtpWebRequest. The FtpWebRequest unfortunately does not support the MLSD command, which is the only portable way to retrieve directory listing with file attributes in FTP protocol. See also Checking if object on FTP server is file or directory.
Your options are:
Do an operation on a file name that is certain to fail for file and succeeds for directories (or vice versa). I.e. you can try to download the "name". If that succeeds, it's a file, if that fails, it's a directory.
You may be lucky and in your specific case, you can tell a file from a directory by a file name (i.e. all your files have an extension, while subdirectories do not)
You use a long directory listing (LIST command = ListDirectoryDetails method) and try to parse a server-specific listing. Many FTP servers use *nix-style listing, where you identify a directory by the d at the very beginning of the entry. But many servers use a different format. The following example uses this approach (assuming the *nix format)
Sub DownloadFtpDirectory(
url As String, credentials As NetworkCredential, localPath As String)
Dim listRequest As FtpWebRequest = WebRequest.Create(url)
listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails
listRequest.Credentials = credentials
Dim lines As List(Of String) = New List(Of String)
Using listResponse As FtpWebResponse = listRequest.GetResponse(),
listStream As Stream = listResponse.GetResponseStream(),
listReader As StreamReader = New StreamReader(listStream)
While Not listReader.EndOfStream
lines.Add(listReader.ReadLine())
End While
End Using
For Each line As String In lines
Dim tokens As String() =
line.Split(New Char() {" "}, 9, StringSplitOptions.RemoveEmptyEntries)
Dim name As String = tokens(8)
Dim permissions As String = tokens(0)
Dim localFilePath As String = Path.Combine(localPath, name)
Dim fileUrl As String = url + name
If permissions(0) = "d" Then
If Not Directory.Exists(localFilePath) Then
Directory.CreateDirectory(localFilePath)
End If
DownloadFtpDirectory(fileUrl + "/", credentials, localFilePath)
Else
Dim downloadRequest As FtpWebRequest = WebRequest.Create(fileUrl)
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile
downloadRequest.Credentials = credentials
Using downloadResponse As FtpWebResponse = downloadRequest.GetResponse(),
sourceStream As Stream = downloadResponse.GetResponseStream(),
targetStream As Stream = File.Create(localFilePath)
Dim buffer As Byte() = New Byte(10240 - 1) {}
Dim read As Integer
Do
read = sourceStream.Read(buffer, 0, buffer.Length)
If read > 0 Then
targetStream.Write(buffer, 0, read)
End If
Loop While read > 0
End Using
End If
Next
End Sub
Use the function like:
Dim credentials As NetworkCredential = New NetworkCredential("user", "mypassword")
Dim url As String = "ftp://ftp.example.com/directory/to/download/"
DownloadFtpDirectory(url, credentials, "C:\target\directory")
If you want to avoid troubles with parsing the server-specific directory listing formats, use a 3rd party library that supports the MLSD command and/or parsing various LIST listing formats; and recursive downloads.
For example with WinSCP .NET assembly you can download whole directory with a single call to the Session.GetFiles:
' Setup session options
Dim SessionOptions As SessionOptions = New SessionOptions
With SessionOptions
.Protocol = Protocol.Ftp
.HostName = "ftp.example.com"
.UserName = "user"
.Password = "mypassword"
End With
Using session As Session = New Session()
' Connect
session.Open(SessionOptions)
' Download files
session.GetFiles("/directory/to/download/*", "C:\target\directory\*").Check()
End Using
Internally, WinSCP uses the MLSD command, if supported by the server. If not, it uses the LIST command and supports dozens of different listing formats.
The Session.GetFiles method is recursive by default.
(I'm the author of WinSCP)
Check out my FTP class: Its pretty straight forward.
Take a look at my FTP class, it might be exactly what you need.
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
To initialize:
Dim ftp As New FORM.FTP("username", "password")
ftp.UploadFile("c:\file.jpeg", "ftp://domain/file.jpeg")
ftp.DownloadFile("c:\file.jpeg", "ftp://ftp://domain/file.jpeg")
Dim directory As List(Of String) = ftp.GetDirectory("ftp://ftp.domain.net/")
ListBox1.Items.Clear()
For Each item As String In directory
ListBox1.Items.Add(item)
Next

How to create directory on FTP server

I am using the following code for creating the folder on FTP server ; But its not working in my case :-
Dim sFilePath as string =filepath
Dim ftpResponse1 As FtpWebResponse
Dim ftpRequest1 As FtpWebRequest
Dim IsExists1 As Boolean = True
ftpRequest1 = CType(FtpWebRequest.Create(sFilePath), FtpWebRequest)
ftpRequest1.UseBinary = True
ftpRequest1.Credentials = New NetworkCredential(ZXFTPUSER, ZXFTPPASS)
ftpRequest1.UsePassive = True
ftpRequest1.Method = WebRequestMethods.Ftp.MakeDirectory
'ftpRequest1.KeepAlive = False
'ftpResponse1 = ftpRequest1.GetResponse()
'ftpResponse1 = ftpRequest1.GetResponse()
'Dim strstream1 As Stream = ftpResponse1.GetResponseStream()
'Dim strreader1 As New StreamReader(strstream1)
'Console.WriteLine(strreader1.ReadToEnd())
'strreader1.Close()
'strstream1.Close()
'ftpResponse1.Close()
Please help me.
In the above case i am not getting any error but when i am going to upload a rar file then it is giving the following exception
The remote server returned an error: (550) File unavailable (e.g., file not found, no access).
And File Upload code is given below
Public Sub FTPUpload(ByVal SourceFile() As IO.FileInfo, ByVal folderLevel As Integer, ByVal ftpPassiveMode As Boolean)
ZXFTPPASS = "******"
Dim filePath As New IO.DirectoryInfo(filePaths)
Dim ftpRequest As FtpWebRequest
Dim dResult As Windows.Forms.DialogResult
Dim ftpFilePath As String = ""
Dim levelPath As String = ""
Dim iLoop As Integer
Dim uFile As IO.FileInfo
For Each uFile In SourceFile
Try
ftpFilePath = levelPath & "/" & uFile.Name
ftpRequest = CType(FtpWebRequest.Create(ftpFilePath), FtpWebRequest)
ftpRequest.Credentials = New NetworkCredential(ZXFTPUSER, ZXFTPPASS)
ftpRequest.UsePassive = ftpPassiveMode
ftpRequest.UseBinary = True
ftpRequest.KeepAlive = False
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile
'Read in the file
Dim b_file() As Byte = System.IO.File.ReadAllBytes(filePath.FullName & "\" & uFile.Name.ToString())
'Upload the file
Dim cls_stream As Stream = ftpRequest.GetRequestStream()
cls_stream.Write(b_file, 0, b_file.Length)
cls_stream.Close()
cls_stream.Dispose()
'MsgBox("Uploaded Successfully", MsgBoxStyle.Information)
Catch
MsgBox("Failed to upload.Please check the ftp settings", MsgBoxStyle.Critical)
End Try
Next
End Sub
Looking through various sites I have found this:
Private Function FtpFolderCreate(folder_name As String, username As String, password As String) As Boolean
Dim request As Net.FtpWebRequest = CType(FtpWebRequest.Create(folder_name), FtpWebRequest)
request.Credentials = New NetworkCredential(username, password)
request.Method = WebRequestMethods.Ftp.MakeDirectory
Try
Using response As FtpWebResponse = DirectCast(request.GetResponse(), FtpWebResponse)
' Folder created
End Using
Catch ex As WebException
Dim response As FtpWebResponse = DirectCast(ex.Response, FtpWebResponse)
' an error occurred
If response.StatusCode = FtpStatusCode.ActionNotTakenFileUnavailable Then
Return False
End If
End Try
Return True
End Function
this is working code on how to create a directory on a FTP server Via Vb.net
Dim folderName As String = "POP/" & Date.Now.Year.ToString & Date.Now.Month.ToString.PadLeft(2, "0"c) & Date.Now.Day.ToString.PadLeft(2, "0"c)
Dim RequestFolderCreate As Net.FtpWebRequest = CType(FtpWebRequest.Create("ftp://" & server & "/" & folderName), FtpWebRequest)
RequestFolderCreate.Credentials = New NetworkCredential(username, password)
RequestFolderCreate.Method = WebRequestMethods.Ftp.MakeDirectory
Try
Using response As FtpWebResponse = DirectCast(RequestFolderCreate.GetResponse(), FtpWebResponse)
End Using
Catch ex As Exception//catch a expection

Using FTP to download each file *WHILE* getting the file list

We need to get about 100 very small files from a remote FTP server using vb.net.
Our company won't let us buy (or install) any 3rd party ftp libraries... so we are forced to use something like FtpWebRequest. (Or is there a better free, choice that is already a part of Visual Studio?)
This method works, but it is VERY slow. (I assume because of the constant logging in/out.)
Log in with user name and password.
Get a file-list from the remote server.
Log out
Use that file-list to get each file separtely:
Log in, get the file, log out.
Log in 99 more times, get each file, log out each time.
Instead, we probably should be doing this, but it never works:
Log in with user name and password. ONCE.
Get a list of filenames.
Download each file.
Log out ONCE.
We found COUNTLESS examples online of "getting an FTP file list" and later "how to download 1 file with FTP"... but we never see "get EACH file name, and download it NOW".
Dim fwr As Net.FtpWebRequest = Net.FtpWebRequest.Create(ftpSite)
fwr.Credentials = New NetworkCredential(userName, password)
fwr.KeepAlive = True
fwr.Method = WebRequestMethods.Ftp.ListDirectory
Dim sr As IO.StreamReader = Nothing
Try
sr = New IO.StreamReader(fwr.GetResponse().GetResponseStream())
Do Until (sr.EndOfStream())
fileName = sr.ReadLine()
fwr.Method = WebRequestMethods.Ftp.DownloadFile
output = ""
Dim sr2 As IO.StreamReader = Nothing
Try
sr2 = New IO.StreamReader(fwr.GetResponse().GetResponseStream())
output = sr2.ReadToEnd()
Catch ex As Exception
End Try
If (Not sr2 Is Nothing) Then sr2.Close() : sr2 = Nothing
Call MsgBox("Got " & fileName & LF & output)
Loop
Catch ex As Exception
End Try
If (Not sr Is Nothing) Then sr.Close() : sr = Nothing
If (Not fwr Is Nothing) Then fwr = Nothing
Take a look at my FTP class, it might be exactly what you need.
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
To initialize:
Dim ftp As New FORM.FTP("username", "password")
ftp.UploadFile("c:\file.jpeg", "ftp://domain/file.jpeg")
ftp.DownloadFile("c:\file.jpeg", "ftp://ftp://domain/file.jpeg")
Dim directory As List(Of String) = ftp.GetDirectory("ftp://ftp.domain.net/")
ListBox1.Items.Clear()
For Each item As String In directory
ListBox1.Items.Add(item)
Next
Something I just put together, the important part is the fwr.Proxy = Nothing, otherwise it tries to auto get the proxy settings which causes huge delays so setting it to nothing forces it to not use one.
If you are using a proxy obviously you need to set this to an actual proxy.
Dim fwr As Net.FtpWebRequest = Net.FtpWebRequest.Create(ftpAddress)
fwr.Credentials = New NetworkCredential(userName, password)
fwr.KeepAlive = True
fwr.Method = WebRequestMethods.Ftp.ListDirectory
fwr.Proxy = Nothing
Try
Dim sr As New IO.StreamReader(fwr.GetResponse().GetResponseStream())
Dim lst = sr.ReadToEnd().Split(vbNewLine)
For Each file As String In lst
file = file.Trim() 'remove any whitespace
If file = ".." OrElse file = "." Then Continue For
Dim fwr2 As Net.FtpWebRequest = Net.FtpWebRequest.Create(ftpAddress & file)
fwr2.Credentials = fwr.Credentials
fwr2.KeepAlive = True
fwr2.Method = WebRequestMethods.Ftp.DownloadFile
fwr2.Proxy = Nothing
Dim fileSR As New IO.StreamReader(fwr2.GetResponse().GetResponseStream())
Dim fileData = fileSR.ReadToEnd()
fileSR.Close()
Next
sr.Close()
Catch ex As Exception
End Try
I know its a bit late but hopefully helps

vb.net 2005, threading file locking issue, I think

I'm using vb.net 2005, I've got the following code running a thread to download a file. However, the process fails sometimes when trying to read the local copy of the file. I think I may need to unlock the local file somehow but I'm not sure how to do this. Can someone take a look and advise me ?
Dim BP1Ended As Boolean = False
Private Sub BackgroundProcess1()
BP1Ended = False
mPadFileStatus = DownloadFile(mstrPadUrl, mLocalFile)
BP1Ended = True
End Sub
'---'
Dim t As System.Threading.Thread
t = New System.Threading.Thread(AddressOf BackgroundProcess1)
t.Start()
Dim ProcessStartTime As Date = Now()
Do While ProcessStartTime.AddMinutes(1) >= Date.Now
Application.DoEvents()
If BP1Ended = True Then
Exit Do
End If
Loop
t.Abort()
PadFileStatus = mPadFileStatus
If BP1Ended = False Then
Application.DoEvents()
AddConsoleMsg("Downloading file.... Aborted", True)
End If
'---'
Public Function DownloadFile(ByVal pstrRequestedFile As String, ByVal pstrDestinationFile As String, Optional ByVal TimeOut As Integer = 120) As DownloadStatus
Dim input As IO.Stream
Dim Req As System.Net.HttpWebRequest = Nothing
Dim Response As System.Net.HttpWebResponse
Try
Req = System.Net.HttpWebRequest.Create(pstrRequestedFile)
Catch ex As Exception
Return DownloadStatus.UnknownError
End Try
Req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
Req.Timeout = TimeOut * 1000 '120 * 1000 '1 second = 1 000 milliseconds
Try
Response = Req.GetResponse
input = Response.GetResponseStream
Dim streamreader As New StreamReader(input, System.Text.Encoding.GetEncoding("windows-1252")) 'System.Text.Encoding.UTF8)'
Dim s_response As String = streamreader.ReadToEnd()
streamreader.Close()
Dim filestream As New FileStream(pstrDestinationFile, FileMode.Create)
Dim streamwriter As New StreamWriter(filestream, System.Text.Encoding.GetEncoding("windows-1252")) ' System.Text.Encoding.UTF8)'
streamwriter.Write(s_response)
streamwriter.Flush()
streamwriter.Close()
Dim length As Long = 1000000 * 100
Dim pos As Long = 0
If Response.ContentLength > 0 Then
length = Response.ContentLength
End If
If length > 0 Then
Return DownloadStatus.OK
End If
input.Close()
Catch ew As System.Net.WebException
If ew.Status = WebExceptionStatus.NameResolutionFailure Or ew.Status = WebExceptionStatus.ProtocolError Then
Return DownloadStatus.FileNotFound
ElseIf ew.Status <> WebExceptionStatus.Success Then
Return DownloadStatus.UnknownError
End If
'Dim errorRespone As HttpWebResponse = CType(ew.Response, HttpWebResponse)
'If errorRespone.StatusCode = HttpStatusCode.NotFound Then '404
' Return DownloadStatus.FileNotFound
'Else
' Return DownloadStatus.UnknownError
'End If'
Catch ex As Exception 'Don't know'
Return DownloadStatus.UnknownError
End Try
End Function
'---'
Dim OpenFile As FileStream
'OpenFile = New FileStream(pstrPadFile, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)
'FAILS HERE
OpenFile = New FileStream(pstrPadFile, FileMode.Open, FileAccess.Read, FileShare.Read)
You don't close the file stream in case of exception which might lead to the lock. Make sure you always dispose disposable resources by wrapping them in Using statements:
Using filestream As FileStream = New FileStream(pstrDestinationFile, FileMode.Create)
Using streamwriter As StreamWriter = New StreamWriter(filestream, Encoding.GetEncoding("windows-1252"))
streamwriter.Write(s_response)
End Using
End Using
Same stands true for the response and response streams. They should be properly disposed.
Also you may consider using the WebClient class which has methods like DownloadFile and DownloadData which could make your life much easier.