I Want to add a Timestamp with the original Name of the Folders name that is being Copied (in vb.net) - 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.

Related

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

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)

Unexpected behaviour inside of nested loops

My Code
Dim fileReader As StreamReader
Dim fileName, temp, strVal As String
For i As Integer = 0 To lbFolder.Items.Count - 1
Dim iText As String = CStr(lbFolder.Items(i))
Dim partPath As String = lblPath.Text + "\" + iText
Dim pathNum As String = partPath + "\2100\"
Dim directory As New DirectoryInfo(pathNum)
Dim fileArr As FileInfo() = directory.GetFiles() ' Get a reference to each file in that directory.
' Display the names of the files.
Dim xItem As FileInfo
For Each xItem In fileArr
lblFname.Text = xItem.ToString
strVal = pathNum & xItem.ToString
lbFiles.Items.Add(strVal)
Next
For j = 0 To lbFiles.Items.Count - 1
fileReader = File.OpenText(pathNum + xItem.ToString)
temp = fileReader.ReadToEnd
File.AppendAllText(partPath + "\2100\" + "2100_Merged.txt", temp)
Next j
lbFiles.Items.Clear()
Next i
End Sub
I have a directory with nested folders. With many children and each child having 4 subchilds and each sub child has 4 files.
Parent
...Child
......subchild1
.........File 1
.........File 2
.........File 3
.........File 4
......subchild2
......subchild3
......subchild4
My Intent is to look at each child then bring merge all of the files into one txt file and then move onto the next subchild.
Pseudo Code might look like
open Subchild folder
for each file in subchild folder
listbox.additem(file)
next
for each item in listbox
add to temp file
next
output tmp file
next subchild
What is happening is that when going through the
for each xItem in filArr
the next series of iText is occurring which I can see through the watch.
This happens even if I have a break at the first next.
How can I correct this?
**Edit*****
For those that might want to test this out here is my entire code.
It requires 2 listboxes, 2 labels , 2 buttons
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
'open folders
Dim dialog = New FolderBrowserDialog()
dialog.SelectedPath = Application.StartupPath
If DialogResult.OK = dialog.ShowDialog() Then
lblPath.Text = dialog.SelectedPath
End If
For Each folder As String In System.IO.Directory.GetDirectories(lblPath.Text)
lbFolder.Items.Add(Path.GetFileName(folder))
Next
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim found700 As Boolean
Dim fileReader As StreamReader
Dim fileName, temp, strVal As String
For i As Integer = 0 To lbFolder.Items.Count - 1
Dim iText As String = CStr(lbFolder.Items(i))
Dim partPath As String = lblPath.Text + "\" + iText
Dim pathNum As String = partPath + "\2100\"
Dim directory As New DirectoryInfo(pathNum)
Dim fileArr As FileInfo() = directory.GetFiles() ' Get a reference to each file in that directory.
' Display the names of the files.
Dim xItem As FileInfo
For Each xItem In fileArr
lblFname.Text = xItem.ToString
strVal = pathNum & xItem.ToString
lbFiles.Items.Add(strVal)
Next
For j = 0 To lbFiles.Items.Count - 1
fileReader = File.OpenText(pathNum + xItem.ToString)
temp = fileReader.ReadToEnd
File.AppendAllText(pathNum + "2100_Merged.txt", temp)
Next j
lbFiles.Items.Clear()
Next i
End Sub
In your second For loop, change pathNum + xItem.ToString to lbFiles.Items.Item(j)
For j = 0 To lbFiles.Items.Count - 1
fileReader = File.OpenText(lbFiles.Items.Item(j))
temp = fileReader.ReadToEnd
File.AppendAllText(partPath + "\2100\" + "2100_Merged.txt", temp)
Next j
Or
For Each f In lbFiles.Items
fileReader = File.OpenText(f)
temp = fileReader.ReadToEnd
File.AppendAllText(partPath + "\2100\" + "2100_Merged.txt", temp)
Next

system.io.ioexception the process cannot access because it is being used by another process

i am getting this problem in some systems, some systems working properly, here my code is,
Dim fileName As String = "FaultTypesByMonth.csv"
Using writer As IO.StreamWriter = New IO.StreamWriter(fileName, True, System.Text.Encoding.Default) '------------ rao new ----
Dim Str As String
Dim i As Integer
Dim j As Integer
Dim headertext1(rsTerms.Columns.Count) As String
Dim k As Integer = 0
Dim arrcols As String = Nothing
For Each column As DataColumn In TempTab.Columns
arrcols += column.ColumnName.ToString() + ","c
k += 1
Next
writer.WriteLine(arrcols)
For i = 0 To (TempTab.Rows.Count - 1)
For j = 0 To (TempTab.Columns.Count - 1)
If j = (TempTab.Columns.Count - 1) Then
Str = (TempTab.Rows(i)(j).ToString)
Else
Str = (TempTab.Rows(i)(j).ToString & ",")
End If
writer.Write(Str)
Next
writer.WriteLine()
Next
writer.Close()
writer.Dispose()
End Using
Dim FileToDelete As String = Nothing
Dim sd As New SaveFileDialog
sd.Filter = "CSV Files (*.csv)|*.csv"
sd.FileName = "FaultTypesByMonth"
If sd.ShowDialog = Windows.Forms.DialogResult.OK Then
FileCopy(fileName, sd.FileName)
MsgBox(" File Saved in selected path")
FileToDelete = fileName
If System.IO.File.Exists(FileToDelete) = True Then
System.IO.File.Delete(FileToDelete)
End If
End If
FileToDelete = fileName
If System.IO.File.Exists(FileToDelete) = True Then
System.IO.File.Delete(FileToDelete)
End If
when i am trying to save this file in desired path, then i am getting this error.
if save in shared folder i am not getting this error
system.io.ioexception the process cannot access because it is being used by another process...
what i am doing wrong,Help me

Load Image files from folder

I have a checked list box and a thumbnail area to display them where I am trying to load only images from a specific folder and need to display in thumbnails area but the problem is there is a thumbs.db file which is also being added to the checked list box which I don't need it.
So how do I actually load only the image files without the thumbs.db file.
Here is my code:
Private Sub LoadProjectToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles LoadProjectToolStripMenuItem.Click
Using ofdlg As New Windows.Forms.OpenFileDialog
ofdlg.DefaultExt = "trk"
ofdlg.Filter = "Project|*.trk"
ofdlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
If ofdlg.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim SaveData As New gCanvasData
Using objStreamReader As New StreamReader(ofdlg.FileName)
Dim x As New XmlSerializer(GetType(gCanvasData))
SaveData = CType(x.Deserialize(objStreamReader), gCanvasData)
objStreamReader.Close()
End Using
With SaveData
'gTSSizer_gAZoom.Value = 100
GCanvas1.ImageXYReset()
GCanvas1.Image = .Image
GCanvas1.gAnnotates = .gAnnotates
GCanvas1.RebuildAll()
GCanvas1.AssembleBitmap()
End With
Dim fullpath As String
fullpath = Application.StartupPath + "\" & System.IO.Path.GetFileNameWithoutExtension(ofdlg.FileName) + "\"
For Each fi As FileInfo In New DirectoryInfo(fullpath).GetFiles
CheckedListBox1.Items.Add(Application.StartupPath + "\" & System.IO.Path.GetFullPath(ofdlg.FileName))
For i As Integer = 0 To CheckedListBox1.Items.Count - 1
CheckedListBox1.SetItemChecked(i, True)
ThumbControl1.AddFolder(fullpath, True)
Next i
Next
End If
End Using
End Sub
Either filter it inside of the For Each Loop:
For Each fi As FileInfo In New DirectoryInfo(fullpath).GetFiles
If Not {".jpg", ".png", ".bmp"}.Contains(fi.Extension) Then Continue For
' ...
Next
or do it in the GetFiles:
DirectoryInfo(fullpath).GetFiles(".jpg")
Found the solution at last:
Dim fullpath As String
fullpath = Application.StartupPath & "\" & System.IO.Path.GetFileNameWithoutExtension(ofdlg.FileName) + "\"
Dim FileDirectory As New IO.DirectoryInfo(fullpath)
Dim FileJpg As IO.FileInfo() = FileDirectory.GetFiles("*.jpg")
Dim FileGif As IO.FileInfo() = FileDirectory.GetFiles("*.gif")
Dim FileBmp As IO.FileInfo() = FileDirectory.GetFiles("*.bmp")
For Each File As IO.FileInfo In FileJpg
CheckedListBox1.Items.Add(File.FullName)
Dim str As String
str = Directory.GetCurrentDirectory() & "\" & "Backup\"
Next
For Each File As IO.FileInfo In FileGif
CheckedListBox1.Items.Add(File.FullName)
Dim str As String
str = Directory.GetCurrentDirectory() & "\" & "Backup\"
Next
For Each File As IO.FileInfo In FileBmp
CheckedListBox1.Items.Add(File.FullName)
Dim str As String
str = Directory.GetCurrentDirectory() & "\" & "Backup\"
Next
For i As Integer = 0 To CheckedListBox1.Items.Count - 1
CheckedListBox1.SetItemChecked(i, True)
Next i
Change DirectoryInfo(fullpath).GetFiles to DirectoryInfo(fullpath).EnumerateFiles() And add a search pattern for the image file extensions you want. http://msdn.microsoft.com/en-us/library/dd383574.aspx