I made a little program that downloads a .zip file from my website and then later it installs in a specific directory. It works fine unless a file with the same name already exists, then I get an error. This is the code I have.
If Form1.CheckBox1.Checked = True Then
Label4.Text = "Downloading Test File!"
wc.DownloadFileAsync(New Uri("http://www.example.com/TestFile.zip"), Directory + "\TestFile.zip")
While wc.IsBusy = True
Application.DoEvents()
End While
ListBox1.Items.Add("Test File")
End If
'Install
If Form1.CheckBox1.Checked = True Then
ZipFile.ExtractToDirectory(Directory + "\TestFile.zip", Directory_Select.TextBox1.Text)
ListBox2.Items.Add("Test File")
End If
So for example, if the files inside "TestFile.zip" have the same name as Install location, it will give me following error:
The file 'filePath` already exists.
It doesn't finish extracting because a file with the same name already exists. Deleting the file beforehand is not a good solution because there will be multiple files with the same name.
How can I replace while extracting?
Also is there a way to pause the program till the file finishes extracting since some files are large and it takes some time before they are extracted.
Thanks in advance for helping me out, I am new and still learning. Appreciate your help.
Although the ExtractToDirectory method doesn't support overwriting files by default, the ExtractToFile method has an overload which takes a second boolean variable that allows you to overwrite the file being extracted. What you can do is to iterate over the files inside the archive and extract them one by one using ExtractToFile(filePath, True).
I have created an extension method which does just that and have been using it for a while. Hope you find it useful!
Add the following module to your project:
Module ZipArchiveExtensions
<System.Runtime.CompilerServices.Extension>
Public Sub ExtractToDirectory(archive As ZipArchive,
destinationDirPath As String, overwrite As Boolean)
If Not overwrite Then
' Use the original method.
archive.ExtractToDirectory(destinationDirPath)
Exit Sub
End If
For Each entry As ZipArchiveEntry In archive.Entries
Dim fullPath As String = Path.Combine(destinationDirPath, entry.FullName)
' If it's a directory, it doesn't have a "Name".
If String.IsNullOrEmpty(entry.Name) Then
Directory.CreateDirectory(Path.GetDirectoryName(fullPath))
Else
entry.ExtractToFile(fullPath, True)
End If
Next entry
End Sub
End Module
Usage:
Using archive = ZipFile.OpenRead(archiveFilePath)
archive.ExtractToDirectory(destPath, True)
End Using
Side note: Don't concatenate strings to form a path out of its parts; use Path.Combine() instead.
Related
I have currently created code which grabs a ceratin file extension and puts it into a certain folder.
My.Computer.FileSystem.CreateDirectory(
"C:\Users\bj\Desktop\Excel Files")
Dim filePaths31 = IO.Directory.GetFiles("C:\Users\bj\Desktop\", "*.xlsx")
For Each filePath31 In filePaths31
Dim filename31 = IO.Path.GetFileName(filePath31)
Dim newPath31 = IO.Path.Combine("C:\Users\bj\Desktop\Excel Files", filename31)
If IO.File.Exists(newPath31) Then
MessageBox.Show("Error: Please check if the file elready exists")
Return
End If
IO.File.Move(filePath31, newPath31)
Next filePath31
MessageBox.Show("Excel Files Compiled And Cleaned")
This code works well although the directory implemented inside the code and should be different for every user.
I have experimented with this code here which allows a user to select a directory, although now I need help assigning that full directory into IO.Path.Combine(users chosen directory here + \Excel Files, filename31
If FolderBrowserDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
Dim grade As New IO.DirectoryInfo(FolderBrowserDialog1.SelectedPath)
This code I believe grabs the user directory and stores it in the grade variable. I need to figure out how to store that 'grade' variable into my code, and also create a new folder in that directory that is specified in the code.
Basically I'm writing a program what will allow the user to choose a file or directory to copy over a network based on a set of stations and then they type in the location to copy those file/directory to.
I'm getting close to finishing I think but I'm having an issue with the My.Computer.FileSystem.CopyFile() method. I'm checking beforehand to see if the user-selected item to copy is a file or directory but in the case that the user enters a directory for the file to be copied to I get an error telling me that "The given file path ends with a directory separator character.", even though it's the DESTINATION location that it's erroring out on. I need to be able to have it copy a file to a directory if a directory is specified without a filename.
I tried playing around with the Trim functions and copying the name to the end of the destination path but I'm having a hard time getting just the file name of the source file.
Any ideas?
Here's the code for my fileCopy function far-
If (pushFileSelectCheckBox1.Enabled) Then
For Each item As String In stations
copyTo = Path.Combine(copyTo, stations([i].ToString))
copyToLoc = copyTo.ToString
copyToLoc = Path.Combine(copyTo, pushLocationBox1.ToString.Remove(0, 36))
If Directory.Exists(pushFrom1) Then
If (System.IO.Directory.Exists(copyToLoc)) Then
My.Computer.FileSystem.CopyDirectory(pushFrom1, copyToLoc, True)
LogOutput("Directory 1 copied.")
Else
Directory.CreateDirectory(copyToLoc)
LogOutput("Directory created.")
My.Computer.FileSystem.CopyDirectory(pushFrom1, copyToLoc, True)
LogOutput("Directory 1 copied.")
End If
ElseIf File.Exists(pushFrom1) Then
If (System.IO.Directory.Exists(copyToLoc)) Then
My.Computer.FileSystem.CopyFile(pushFrom1, copyToLoc, True)
LogOutput("File 1 copied.")
Else
Directory.CreateDirectory(copyToLoc)
LogOutput("Directory created.")
My.Computer.FileSystem.CopyFile(pushFrom1, copyToLoc, True)
LogOutput("File 1 copied.")
End If
Else
MsgBox("Chosen file, or whatever, is neither a file nor a directory. What did you do?!?!", MsgBoxStyle.Critical, "Umm....")
End If
i += 1
Next
i = 0
End If
Thanks in advance.
Use Path.GetFileName to get the filename from the pushFrom variable and append it at the end of copyToLoc. The second parameter of CopyFile need to end with a filename, not just a path.
I'm making a console application and I want to see what files is in a folder
For Each foundFile As String In My.Computer.FileSystem.GetFiles("c:\users\zac\desktop\booked vehicle\requested\")
Console.WriteLine(foundFile)
Next
after using this code and find that the folder is empty I need an If statement that say's
If foundfile has no files then
tell user no files found
end if
but I don't know how to write this so Visual Basic understands.
Load the files into a variable then check the count.
Dim files = My.Computer.FileSystem.GetFiles("c:\users\zac\desktop\booked vehicle\requested\")
If files.Count = 0 Then
'tell user no files
Else
For Each file In files
Console.WriteLine(file)
Next
End If
FileSystem.GetFiles() returns a collection of file name strings. As OneFineDay showed, you can use the collection's Count property to know if any files were found.
The downside of using FileSystem.GetFile() is that it has to search the entire folder before then returning the entire list of filenames. If you are searching large folders and speed is an issue, consider using Directory.EnumerateFiles() instead. That way, you can output a message if no file was found, otherwise loop throuh the list of found files. For example:
Dim files = Directory.EnumerateFiles("c:\users\zac\desktop\booked vehicle\requested\").GetEnumerator()
If files.MoveNext Then
' files were found
Do
Console.WriteLine(files.Current)
Loop Until Not files.MoveNext
Else
' no files were found
End If
I personally would use Linq to accomplish this. It's very quick and efficient to use in this case. I put the Console.ReadLine() at the end to show the files, you can remove this if need to be. Also you can change the Console.WriteLine to not include the string (s) if you don't want to. The s was declared if you want to show the files and also to see if there are any files. As I said, this was for my viewing to see the files. Straight to the point!
Dim s As String = String.Join(Environment.NewLine, New DirectoryInfo("YOUR DIRECTORY").GetFiles().[Select](Function(file) file.Name).ToArray)
Console.WriteLine(If(s.Length > 0, s, "No files found!"))
Console.ReadLine()
I check for the existence of the file with File.Exists(filePath). Then I try to open the file from within Excel with Excel.Workbooks.OpenText(filePath). But Excel complains that the file's not there. What the heck?
The context is that I am shelling out to another application to process a given file and produce a .out file, which I then convert to an Excel workbook.
'' At this point, filePath is a .txt file.
Dim args As String = String.Format("""{0}""", filePath)
...
Dim exe As String = Config.ExtractEXE
Dim i As New ProcessStartInfo(exe)
i.Arguments = args
Dim p As Process = Process.Start(i)
p.WaitForExit()
...
'' filePath now becomes the .out file.
'' Then eventually, I get around to checking:
'If Not File.Exists(filePath) Then
' MsgBox("Please ensure...")
' Exit Sub
'End If
'' In response to an answer, I no longer check for the existence of the file, but
'' instead try to open the file.
Private Function fileIsReady(filePath As String) As Boolean
Try
Using fs As FileStream = File.OpenRead(filePath)
Return True
End Using
Catch
Return False
End Try
End Function
Do Until fileIsReady(filePath)
'' Wait.
Loop
ExcelFile.Convert(filePath...)
'' Wherein I make the call to:
Excel.Workbooks.OpenText(filePath...)
'' Which fails because filePath can't be found.
Is there a latency issue, such that .Net recognizes the existence of the file before it's accessible to other applications? I just don't understand why File.Exists() can tell me the file is there and then Excel can't find it.
As far as I know, the only application that might have the file open is the application I call to do the processing. But that application should be finished with the file by the time p.WaitForExit() finishes, right?
I've had to deploy the application with this as a known bug, which really sucks. There's an easy workaround for the user; but still--this bug should not be. Hope you can help.
Whether or not a file exists is not the only factor in whether you can open it. You also need to look at file system permissions and locking.
File.Exists can lie to you (it returns false if you pass a directory path or if any error occurs, even if the file does exist)
The file system is volatile, and things can change even in the brief period between an if (File.Exists(...)) line and trying to open the file in the next line.
In summary: you should hardly ever use file.exists(). Almost any time you are tempted to do so, just try to open the file and make sure you have a good exception handler instead.
I wrote myself a little downloading application so that I could easily grab a set of files from my server and put them all onto a new pc with a clean install of Windows, without actually going on the net. Unfortunately I'm having problems creating the folder I want to put them in and am unsure how to go about it.
I want my program to download the apps to program files\any name here\
So basically I need a function that checks if a folder exists, and if it doesn't it creates it.
If Not System.IO.Directory.Exists(YourPath) Then
System.IO.Directory.CreateDirectory(YourPath)
End If
Under System.IO, there is a class called Directory.
Do the following:
If Not Directory.Exists(path) Then
Directory.CreateDirectory(path)
End If
It will ensure that the directory is there.
Try the System.IO.DirectoryInfo class.
The sample from MSDN:
Imports System
Imports System.IO
Public Class Test
Public Shared Sub Main()
' Specify the directories you want to manipulate.
Dim di As DirectoryInfo = New DirectoryInfo("c:\MyDir")
Try
' Determine whether the directory exists.
If di.Exists Then
' Indicate that it already exists.
Console.WriteLine("That path exists already.")
Return
End If
' Try to create the directory.
di.Create()
Console.WriteLine("The directory was created successfully.")
' Delete the directory.
di.Delete()
Console.WriteLine("The directory was deleted successfully.")
Catch e As Exception
Console.WriteLine("The process failed: {0}", e.ToString())
End Try
End Sub
End Class
Since the question didn't specify .NET, this should work in VBScript or VB6.
Dim objFSO, strFolder
strFolder = "C:\Temp"
Set objFSO = CreateObject("Scripting.FileSystemObject")
If Not objFSO.FolderExists(strFolder) Then
objFSO.CreateFolder strFolder
End If
Try this: Directory.Exists(TheFolderName) and Directory.CreateDirectory(TheFolderName)
(You may need: Imports System.IO)
VB.NET? System.IO.Directory.Exists(string path)
Directory.CreateDirectory() should do it.
http://msdn.microsoft.com/en-us/library/system.io.directory.createdirectory(VS.71).aspx
Also, in Vista, you probably cannot write into C: directly unless you run it as an admin, so you might just want to bypass that and create the dir you want in a sub-dir of C: (which i'd say is a good practice to be followed anyways. -- its unbelievable how many people just dump crap onto C:
Hope that helps.
(imports System.IO)
if Not Directory.Exists(Path) then
Directory.CreateDirectory(Path)
end if
If Not Directory.Exists(somePath) then
Directory.CreateDirectory(somePath)
End If
You should try using the File System Object or FSO. There are many methods belonging to this object that check if folders exist as well as creating new folders.
I see how this would work, what would be the process to create a dialog box that allows the user name the folder and place it where you want to.
Cheers
Just do this:
Dim sPath As String = "Folder path here"
If (My.Computer.FileSystem.DirectoryExists(sPath) = False) Then
My.Computer.FileSystem.CreateDirectory(sPath + "/<Folder name>")
Else
'Something else happens, because the folder exists
End If
I declared the folder path as a String (sPath) so that way if you do use it multiple times it can be changed easily but also it can be changed through the program itself.
Hope it helps!
-nfell2009