How to get all files in a subdirectory of isostorage - vb.net

I want to list all files in a subdirectory on istostorage
Public Function GetAllFilesInDirectory(ByVal DirectoryName As String) As List(Of String)
Dim isoStore As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication()
Dim L As New List(Of String)
For Each di As String In isoStore.GetDirectoryNames
If di = DirectoryName Or di & "/" = DirectoryName Then
For Each fi As String In isoStore.GetFileNames'<-- fails because not the subdirectory is listed
If fi.StartsWith(DirectoryName) Then L.Add(fi)
Next
End If
Next
Return L
End Function

I'm not a VB.NET developer, so I used a converter to convert from my old C# version. See if this helps read all directories:
Public Shared Sub GetIsolatedStorageView(pattern As String, storeFile As IsolatedStorageFile)
Dim root As String = System.IO.Path.GetDirectoryName(pattern)
If root <> "" Then
root += "/"
End If
Dim directories As String() = storeFile.GetDirectoryNames(pattern)
'if the root directory has no FOLDERS, then the GetFiles() method won't be called.
'the line below calls the GetFiles() method in this event so files are displayed
'even if there are no folders
If directories.Length = 0 Then
GetFiles(root, "*", storeFile)
End If
For i As Integer = 0 To directories.Length - 1
Dim dir As String = directories(i) + "/"
'Write to output window
Debug.WriteLine(root + directories(i))
'Get all the files from this directory
GetFiles(root + directories(i), pattern, storeFile)
'Continue to get the next directory
GetIsolatedStorageView(root + dir + "*", storeFile)
Next
End Sub
Private Shared Sub GetFiles(dir As String, pattern As String, storeFile As IsolatedStorageFile)
Dim fileString As String = System.IO.Path.GetFileName(pattern)
Dim files As String() = storeFile.GetFileNames(pattern)
Try
For i As Integer = 0 To storeFile.GetFileNames(dir + "/" + fileString).Length - 1
'Files are prefixed with "--"
Debug.WriteLine("--" + dir + "/" + storeFile.GetFileNames(dir + "/" + fileString)(i))
Next
Catch ise As IsolatedStorageException
Debug.WriteLine("An IsolatedStorageException exception has occurred: " + ise.InnerException)
Catch e As Exception
Debug.WriteLine("An exception has occurred: " + e.InnerException)
End Try
End Sub
If you want it for development purposes, you could use the wp7explorer tool instead.

Related

Unable to cast object of type 'System.Object' to type (MyClass) Vb.Net

I am using this code to store the object of my class "Device" to Object but I am getting the "system.invalidcastexception" Exception. I cast it in the same way in other classes and there it worked but here it is not working
Public Class Device
Inherits MainDevice
Private TestData As New SortedList(Of Integer, DataVPAA)
Public Sub New(ByVal version As String, ByVal System As String, ByVal IdNumber As UInteger, ByVal Serial As String)
DataVersion = version
SystemVersion = System
Serial_Number = Serial
IdentNumber = IdNumber
This is where i am getting the Error
Dim obj As Object
obj = LoadXml(GetType(Device), Path)
If obj Is Nothing Then
' Some Logic Here
Else
Dim dev As New Device
dev = CType(obj, Device) '**system.invalidcastexception**
Me.TestData = dev.TestData
' Some Logic Here
End If
End Sub
End Class
Load Function
Function LoadXML(ByVal DeviceType As Type, ByVal Path As String) As Object
Dim obj As New Object
Dim XMLFilePath As String
Dim xmlreader As XmlReader
If Me.GetType = GetType(ABCDevice) Or Me.GetType = GetType(CVDevice) Or Me.GetType = GetType(CV2Device) Then
XMLFilePath = Path + "\" + strIdentNr + "_" + Serial_Number + ".xml"
Else
XMLFilePath = Path + "\" + IdentNumber.ToString + "_" + Serial_Number + ".xml"
End If
'Check if File exists
If File.Exists(XMLFilePath) Then
Dim fs As New FileStream(XMLFilePath, FileMode.Open, FileAccess.Read)
xmlreader = XmlReader.Create(fs)
Try 'Try to deserialize to object
Dim xml_deserializer As New Serialization.XmlSerializer(DeviceType)
If xml_deserializer.CanDeserialize(xmlreader) Then
obj = xml_deserializer.Deserialize(xmlreader)
End If
Catch ex As Exception
MessageBox.Show("XML Deserializer Error: " + ex.Message)
End Try
fs.Close()
Return obj
Else : Return Nothing
End If
End Function
I tried to cast it with different methods like directcast and others but i am getting the same exception.
You can make the LoadXml generic and always return the type you want. Such as
Function LoadXml(Of T)(path As String) As T
Dim obj As T = Nothing
Dim XMLFilePath As String
If Me.GetType = GetType(ABCDevice) Or Me.GetType = GetType(CVDevice) Or Me.GetType = GetType(CV2Device) Then
XMLFilePath = path + "\" + strIdentNr + "_" + Serial_Number + ".xml"
Else
XMLFilePath = path + "\" + IdentNumber.ToString + "_" + Serial_Number + ".xml"
End If
'Check if File exists
If File.Exists(XMLFilePath) Then
Using fs As New FileStream(XMLFilePath, FileMode.Open, FileAccess.Read)
Using reader = XmlReader.Create(fs)
Try 'Try to deserialize to object
Dim xml_deserializer As New Serialization.XmlSerializer(GetType(T))
If xml_deserializer.CanDeserialize(reader) Then
obj = xml_deserializer.Deserialize(reader)
End If
Catch ex As Exception
MessageBox.Show("XML Deserializer Error: " + ex.Message)
End Try
End Using
End Using
End If
Return obj
End Function
Dim dev = LoadXml(Of Device)("path")
Now dev is guaranteed to be a Device. If it's Nothing, it failed

I Want to add a Timestamp with the original Name of the Folders name that is being Copied (in vb.net)

I found some Code to Copy a Folder with all its contents to another folder. the Folder name that is being copied to another folder is the same as the original folder in its original path. I want to add a timestamp with a date and time to show you the most recent 'copy' of the folder you copied.
An example would be:
Original Folder: Rage 2 ;
Copied Folder: Rage 2 - 3/11/2021 - 7:37
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim parts As String() = directoryTargetLocation.Split(New Char() {"\"c})
Dim filename As String = parts(parts.Count - 1) 'target folder name
Dim dir_path As String = "" 'directory without target folder name
For f As Integer = 0 To parts.Count - 2
dir_path += parts(f) + "\"
Next
Dim copied As Integer = 0
Dim counter As Integer = IO.Directory.GetFiles(directoryTargetLocation, "*.*", IO.SearchOption.AllDirectories).Length 'counts the number of files
SetProgressbar(counter, ProgressBar2) 'Sets ProgressBar maximum to number of files
setLabelTxt("Copied (0/" + counter.ToString + ")", Label4) 'displays the amount of copied files
Dim FolderList As New List(Of String)
FolderList.Add(directoryTargetLocation) 'Set first folder
Do While True
If (BackgroundWorker1.CancellationPending = True) Then 'cancel loop
e.Cancel = True
Exit Do
End If
Dim FoldersInsideDirectory As New List(Of String)
If FolderList.Count = 0 Then
Exit Do 'If there is no folder to copy Exit Do
Else
For l As Integer = 0 To FolderList.Count - 1
If (BackgroundWorker1.CancellationPending = True) Then 'stop for loop
e.Cancel = True
Exit For
End If
Dim sourceDirectoryInfo As New System.IO.DirectoryInfo(FolderList(l))
Dim dest As String = FolderList(l).Replace(dir_path, "")
If (Not System.IO.Directory.Exists(Destinydirectory + "\" + dest)) Then 'create subFolder inside directory
System.IO.Directory.CreateDirectory(Destinydirectory + "\" + dest)
End If
Dim fileSystemInfo As System.IO.FileSystemInfo
For Each fileSystemInfo In sourceDirectoryInfo.GetFileSystemInfos
If (BackgroundWorker1.CancellationPending = True) Then
e.Cancel = True
Exit For
End If
Dim destinationFileName As String = System.IO.Path.Combine(Destinydirectory + "\" + dest, fileSystemInfo.Name)
If TypeOf fileSystemInfo Is System.IO.FileInfo Then
Dim streamRead As New System.IO.FileStream(fileSystemInfo.FullName, System.IO.FileMode.Open)
setLabelTxt(fileSystemInfo.FullName.ToString, LabelProgress)
Dim streamWrite As New System.IO.FileStream(Destinydirectory + "\" + dest + "\" + fileSystemInfo.Name, IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.None)
Dim lngLen As Long = streamRead.Length - 1
setLabelTxt("Copy bytes : (0/" + (lngLen * 100).ToString + ")", Label10)
Dim byteBuffer(1048576) As Byte 'our stream buffer
Dim intBytesRead As Integer 'number of bytes read
While streamRead.Position < lngLen 'keep streaming until EOF
If (BackgroundWorker1.CancellationPending = True) Then
e.Cancel = True
Exit While
End If
BackgroundWorker1.ReportProgress(CInt(streamRead.Position / lngLen * 100))
setLabelTxt("Copy bytes : (" + CInt(streamRead.Position).ToString + "/" + (lngLen * 100).ToString + ")", Label10)
intBytesRead = (streamRead.Read(byteBuffer, 0, 1048576))
streamWrite.Write(byteBuffer, 0, intBytesRead)
End While
'Clean up
streamWrite.Flush()
streamWrite.Close()
streamRead.Close()
addProgress(1, ProgressBar2)
copied += 1
setLabelTxt("Copied (" + copied.ToString + "/" + counter.ToString + ")", Label4)
Else
FoldersInsideDirectory.Add(fileSystemInfo.FullName)
End If
Next
Next
FolderList.Clear()
FolderList = FoldersInsideDirectory
End If
Loop
End Sub
Before:
Dim streamWrite As New System.IO.FileStream(Destinydirectory + "\" + dest + "\" + fileSystemInfo.Name, IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.None)
After:
dim fnbase as string = Path.GetFileNameWithoutExtension(fileSystemInfo.Name)
dim fnexten as string = path.getextension(fileSystemInfo.Name)
dim fndate as string = DateTime.Now.ToString("yyyyMMdd HHmmss")
dim fn as string = $"{fnbase} - {fndate}{fnexten}"
Dim streamWrite As New System.IO.FileStream(Destinydirectory + "\" + dest + "\" + fn, IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.None)
I broke this down the way I did just so it was really easy for you to see the different pieces of it. You could just as easily put all of this together dynamically as the value you pass to System.IO.FileStream.
As an aside, you're doing the copy itself the complicated way. Maybe you need to use that method for a specific reason, but if not, maybe consider File.Copy next time.

VB.net Check items in a text doc and see if it's in a folder

I have a text document with a list of file names and their extensions. I need to go through this list and check a directory for the existence of each file. I then need to output the result to either foundFilesList.txt or OrphanedFiles.txt. I have two approaches to this function, and neither is working. The first example uses a loop to cycle through the text doc. The second one doesn't work it never sees a match for the file from the fileNamesList.
Thank you for taking the time to look at this.
First Code:
Dim FILE_NAME As String
FILE_NAME = txtFileName.Text
Dim fileNames = System.IO.File.ReadAllLines(FILE_NAME)
fCount = 0
For i = 0 To fileNames.Count() - 1
Dim fileName = fileNames(i)
'sFileToFind = location & "\" & fileName & "*.*"
Dim paths = IO.Directory.GetFiles(location, fileName, IO.SearchOption.AllDirectories)
If Not paths.Any() Then
System.IO.File.AppendAllText(orphanedFiles, fileName & vbNewLine)
Else
For Each pathAndFileName As String In paths
If System.IO.File.Exists(pathAndFileName) = True Then
Dim sRegLast = pathAndFileName.Substring(pathAndFileName.LastIndexOf("\") + 1)
Dim toFileLoc = System.IO.Path.Combine(createXMLFldr, sRegLast)
Dim moveToFolder = System.IO.Path.Combine(MoveLocation, "XML files", sRegLast)
'if toFileLoc = XML file exists move it into the XML files folder
If System.IO.File.Exists(toFileLoc) = False Then
System.IO.File.Copy(pathAndFileName, moveToFolder, True)
System.IO.File.AppendAllText(ListofFiles, sRegLast & vbNewLine)
fileFilename = (fileName) + vbCrLf
fCount = fCount + 1
BackgroundWorker1.ReportProgress(fCount)
'fileCount.Text = fCount
End If
End If
Next
End If
BackgroundWorker1.ReportProgress(100 * i / fileNames.Count())
'statusText = i & " of " & fileName.Count() & " copied"
fCount = i
Next
Second Code:
FILE_NAME = txtFileName.Text 'textfield with lines of filenames are located ]
Dim fileNamesList = System.IO.File.ReadAllLines(FILE_NAME)
location = txtFolderPath.Text
fCount = 0
' Two list to collect missing and found files
Dim foundFiles As List(Of String) = New List(Of String)()
Dim notfoundFiles As List(Of String) = New List(Of String)()
Dim fileNames As String() = System.IO.Directory.GetFiles(createXMLFldr)
For Each file As String In fileNamesList
Debug.Write("single file : " & file & vbCr)
' Check if the files is contained or not in the request list
Dim paths = IO.Directory.GetFiles(location, file, IO.SearchOption.AllDirectories)
If fileNamesList.Contains(Path.GetFileNameWithoutExtension(file)) Then
Dim FileNameOnly = Path.GetFileName(file)
Debug.Write("FileNameOnly " & FileNameOnly & vbCr)
If System.IO.File.Exists(FileNameOnly) = True Then
'if toFileLoc = XML file exists move it into the XML files folder
Dim moveToFolder = System.IO.Path.Combine(MoveLocation, "XML files", file)
foundFiles.Add(file) 'add to foundFiles list
fileFilename = (file) + vbCrLf 'add file name to listbox
fCount = fCount + 1
Else
notfoundFiles.Add(file)
End If
End If
Next
File.WriteAllLines(ListofFiles, foundFiles)
File.WriteAllLines(orphanedFiles, notfoundFiles)
This is just a starting point for you, but give it a try:
Friend Module Main
Public Sub Main()
Dim oFiles As List(Of String)
Dim _
sOrphanedFiles,
sSearchFolder,
sFoundFiles,
sTargetFile As String
sOrphanedFiles = "D:\Results\OrphanedFiles.txt"
sSearchFolder = "D:\Files"
sFoundFiles = "D:\Results\FoundFiles.txt"
oFiles = IO.File.ReadAllLines("D:\List.txt").ToList
oFiles.ForEach(Sub(File)
If IO.Directory.GetFiles(sSearchFolder, File, IO.SearchOption.AllDirectories).Any Then
sTargetFile = sFoundFiles
Else
sTargetFile = sOrphanedFiles
End If
IO.File.AppendAllText(sTargetFile, $"{File}{Environment.NewLine}")
End Sub)
End Sub
End Module
If I've misjudged the requirements, let me know and I'll update accordingly.
Explanations and comments in-line.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'I presume txtFileName.Text contains the full path including the file name
'I also presume that this text file contains only file names with extensions
Dim FilesInTextFile = System.IO.File.ReadAllLines(txtFileName.Text)
'Instead of accessing the Directory over and over, just get an array of all the files into memory
'This should be faster than searching the Directory structure one by one
'Replace <DirectoryPathToSearch> with the actual path of the Directory you want to search
Dim FilesInDirectory = IO.Directory.GetFiles("<DirectoryPathToSearch>", "*.*", IO.SearchOption.AllDirectories)
'We now have an array of full path and file names but we just need the file name for comparison
Dim FileNamesInDirectory = From p In FilesInDirectory
Select Path.GetFileName(p)
'A string builder is more efficient than reassigning a string with &= because a
'string build is mutable
Dim sbFound As New StringBuilder
Dim sbOrphan As New StringBuilder
'Instead of opening a file, writing to the file and closing the file
'in the loop, just append to the string builder
For Each f In FilesInTextFile
If FileNamesInDirectory.Contains(f) Then
sbFound.AppendLine(f)
Else
sbOrphan.AppendLine(f)
End If
Next
'After the loop write to the files just once.
'Replace the file path with the actual path you want to use
IO.File.AppendAllText("C:\FoundFiles.txt", sbFound.ToString)
IO.File.AppendAllText("C:\OrphanFiles.txt", sbOrphan.ToString)
End Sub

Downloading files code gets unexpected 404 error

My code downloads files in loop but after the last file downloads it keeps downloading files that aren't there. Website shows redirect and 404 error.
I'm new with visual basic so I'm asking for help here.
My.Computer.Network.DownloadFile(strFullUrlDownload, strFullSavePath, False, 1000)
404 error
redirect
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim strMainUrl As String = "http://jixxer.com/123/"
Dim dt As DateTime = DateTime.Now
Dim dtDate As String = dt.ToString("yyyy-MM-dd")
Dim strSlash As String = "/"
Dim strPdf As String = "pdf"
Dim strDot As String = "."
Dim strPage As String = "page"
Dim strPageNbr As String = 1
Dim intCounter As Integer = 1
Dim strPageCounter As String = String.Format("{0:000}", intCounter)
Dim strSavePath As String = "D:\dls\title1\"
Dim strFullSavePath As String = strSavePath & strPageCounter & strDot & strPdf
Dim strFullUrlDownload As String = strMainUrl & dtDate & strSlash & strPdf & strSlash & strPage & strPageNbr & strDot & strPdf
Do Until strPageCounter = 200
' Downloads the resource with the specified URI to a local file.
My.Computer.Network.DownloadFile(strFullUrlDownload, strFullSavePath, False, 1000)
intCounter = intCounter + 1
strPageNbr = strPageNbr + 1
strPageCounter = String.Format("{0:000}", intCounter)
strFullSavePath = strSavePath & strPageCounter & strDot & strPdf
strFullUrlDownload = strMainUrl & dtDate & strSlash & strPdf & strSlash & strPage & strPageNbr & strDot & strPdf
Loop
End Sub
End Class
Try
'TRY to download the file using https first...
My.Computer.Network.DownloadFile(New Uri("https://" & ServerAddress & WebLogoPath & Convert.ToString(RowArray(0)) & ".png"), Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\" & AppDataFolder & PCLogoPath & Convert.ToString(RowArray(0)) & ".png", "", "", False, 500, True)
Catch ex_https As Exception
'Unable to locate file or write file
'If the operation timed out...
If (ex_https.Message = "The operation has timed out") Then
'Re-TRY to download the file using http instead, as a time out error may indicate that HTTPS is not supported.
Try
My.Computer.Network.DownloadFile(New Uri("http://" & ServerAddress & WebLogoPath & Convert.ToString(RowArray(0)) & ".png"), Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\" & AppDataFolder & PCLogoPath & Convert.ToString(RowArray(0)) & ".png", "", "", False, 500, True)
Catch ex_http As Exception
'Most likely, the file doesn't exist on the server. Either way, we cannot obtain the file so we need to perform the same action,
'which is handled outside of this Try block.
End Try
Else
'This is most likely a 404 error. Either way, we cannot obtain the file (and the connection is not timing out) - so
'we need to perform the same action, which is handled outside of this Try block.
End If
End Try
I just put the counter at 200 to test and make sure it works. But I know I need a way to quit on error but not sure how to code it yet. Appreciate any help.
If you don't know how many documents are stored in that remote directory, you have to handle the exception when a page is not found.
It's always possible to receive WebExceptions when a resource is requested from a site, so you should handle this case anyway.
I suggest to use the WebClient class directly instead of Network.DownloadFile(), which may be handy if you want to show a predefined UI of the progress (when it's possible), but using WebClient directly, lets you perform the download asynchrounously if you need it to, using the async/await pattern and the WebClient.DownloadFileTaskAsync() method.
Another suggestion: use a method to download those files, so you can call it from anywhere in your code. You can use a class or a module to store your methods, so you don't clutter your UI and you can also easily reuse these classes or modules in different projects, just including in a project the file that contains them.
Your code could be modified as follow (synchronous version):
You need to pass to the DownloadPdfPages method the remote base address: http://jixxer.com/123, the Path where the files are store (filesPath).
The third and fourth parameters are optional:
- If you don't specify a resourceName, Date.Now.ToString("yyyy-MM-dd") is assumed,
- If you don't specify a startPage, it will default to 1, converted in page1.pdf (the example here asks to start from page 3).
Note: I'm using String Interpolation here: $"page{startPage + pageCount}.pdf".
If your VB.Net version doesn't support it, use String.Format() instead.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim numberOfPages = DownloadPdfPages("http://jixxer.com/123", "D:\dls\title1", "", 3)
If numberOfPages > 0 Then
MessageBox.Show($"Download completed. Number of pages: {numberOfPages}")
Else
MessageBox.Show("Download failed")
End If
End Sub
Private Function DownloadPdfPages(baseAddress As String, filesPath As String, Optional resourceName As String = "", Optional startPage As Integer = 1) As Integer
If String.IsNullOrEmpty(resourceName) Then resourceName = Date.Now.ToString("yyyy-MM-dd")
Dim resourceAddr = Path.Combine(baseAddress, resourceName, "pdf")
Dim pageCount = 0
Dim client = New WebClient()
Try
Do
Dim documentName = $"page{startPage + pageCount}.pdf"
Dim resourceUri = New Uri(Path.Combine(resourceAddr, documentName), UriKind.Absolute)
Dim fileName = Path.Combine(filesPath, documentName)
client.DownloadFile(resourceUri, fileName)
pageCount += 1
Loop
Catch ex As WebException
If ex.Response IsNot Nothing Then
Dim statusCode = DirectCast(ex.Response, HttpWebResponse).StatusCode
If statusCode = HttpStatusCode.NotFound Then
Return pageCount
End If
ElseIf ex.Status = WebExceptionStatus.ProtocolError AndAlso ex.Message.Contains("404") Then
Return pageCount
Else
' Log and/or ...
Throw
End If
Return 0
Finally
client.Dispose()
End Try
End Function
Asynchronous version, using the WebClient.DownloadFileTaskAsync() method.
Just a few changes ae necessary, note the Async keyword added to both the Button.Click handler and the DownloadPdfPagesAsync() method.
The Await keyword is then used to wait for a method to complete, without blocking the UI:
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim numberOfPages = Await DownloadPdfPagesAsync("http://jixxer.com/123", "D:\dls\title1", "", 3)
If numberOfPages > 0 Then
MessageBox.Show($"Download completed. Number of pages: {numberOfPages}")
Else
MessageBox.Show("Download failed")
End If
End Sub
Private Async Function DownloadPdfPagesAsync(baseAddress As String, filesPath As String, Optional resourceName As String = "", Optional startPage As Integer = 1) As Task(Of Integer)
If String.IsNullOrEmpty(resourceName) Then resourceName = Date.Now.ToString("yyyy-MM-dd")
Dim resourceAddr = Path.Combine(baseAddress, resourceName, "pdf")
Dim pageCount = 0
Dim client = New WebClient()
Try
Do
Dim documentName = $"page{startPage + pageCount}.pdf"
Dim resourceUri = New Uri(Path.Combine(resourceAddr, documentName), UriKind.Absolute)
Dim fileName = Path.Combine(filesPath, documentName)
Await client.DownloadFileTaskAsync(resourceUri, fileName)
pageCount += 1
Loop
Catch ex As WebException
If ex.Response IsNot Nothing Then
Dim statusCode = DirectCast(ex.Response, HttpWebResponse).StatusCode
If statusCode = HttpStatusCode.NotFound Then
Return pageCount
End If
ElseIf ex.Status = WebExceptionStatus.ProtocolError AndAlso ex.Message.Contains("404") Then
Return pageCount
Else
' Log and/or ...
Throw
End If
Return 0
Finally
client.Dispose()
End Try
End Function

Copying same file to multiple locations / drives with progress bar

I am trying to make a vb.net appliaction designed to copy one file to multiple locations at the same time. But I can't figure out how to stop the System.IO.IOException I am receiving because multiple threads are trying to access the file. Here is my current code:
Dim parts As String() = targ.Split(New Char() {"\"c})
Dim filename As String = parts(parts.Count - 1) 'target folder name
Dim dir_path As String = "" 'directory without target folder name
Dim FolderList As New List(Of String)
Dim copied As Integer = 0<
For f As Integer = 0 To parts.Count - 2
dir_path += parts(f) + "\"
Next
Dim counter As Integer = IO.Directory.GetFiles(targ, "*.*", IO.SearchOption.AllDirectories).Length 'counts the number of files
newitm.SubItems(4).Text = "Copied (0/" + counter.ToString + ")" 'displays the amount of copied files
FolderList.Add(targ) 'Set first folder
Do While True
Dim FoldersInsideDirectory As New List(Of String)
If FolderList.Count = 0 Then
Exit Do 'If there is no folder to copy Exit Do
Else
For l As Integer = 0 To FolderList.Count - 1
Dim fileSystemInfo As System.IO.FileSystemInfo
Dim sourceDirectoryInfo As New System.IO.DirectoryInfo(FolderList(l))
Dim dest As String = FolderList(l).Replace(dir_path, "")
If (Not System.IO.Directory.Exists(des + "\" + dest)) Then 'create subFolder inside directory
System.IO.Directory.CreateDirectory(des + "\" + dest)
End If
For Each fileSystemInfo In sourceDirectoryInfo.GetFileSystemInfos
Dim destinationFileName As String = System.IO.Path.Combine(des + "\" + dest, fileSystemInfo.Name)
If TypeOf fileSystemInfo Is System.IO.FileInfo Then
Dim streamRead As New System.IO.FileStream(fileSystemInfo.FullName, System.IO.FileMode.Open)
Dim streamWrite As New System.IO.FileStream(des + "\" + dest + "\" + fileSystemInfo.Name, IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.None)
Dim lngLen As Long = streamRead.Length - 1
newitm.SubItems(3).Text = "Copy bytes : (0/" + (lngLen * 100).ToString + ")"
Dim byteBuffer(1048576) As Byte 'our stream buffer
Dim intBytesRead As Integer 'number of bytes read
While streamRead.Position < lngLen 'keep streaming until EOF
newitm.SubItems(3).Text = "Copy bytes : (" + CInt(streamRead.Position).ToString + "/" + (lngLen * 100).ToString + ")"
intBytesRead = (streamRead.Read(byteBuffer, 0, 1048576))
streamWrite.Write(byteBuffer, 0, intBytesRead)
streamRead.Flush()
End While
'Clean up
streamWrite.Flush()
streamWrite.Close()
streamRead.Close()
copied += 1
newitm.SubItems(4).Text = "Copied (" + copied.ToString + "/" + counter.ToString + ")"
Else
FoldersInsideDirectory.Add(fileSystemInfo.FullName)
End If
Next
Next
FolderList.Clear()
FolderList = FoldersInsideDirectory
End If
MsgBox("Done")
Loop
You need to specify FileShare.Read in the FileStream's constructor:
Read
Allows subsequent opening of the file for reading. If this flag is not specified, any request to open the file for reading (by this process or another process) will fail until the file is closed.
Dim streamRead As New System.IO.FileStream(fileSystemInfo.FullName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read)