There is a lot of duplication of functions in the My.Computer.FileSystem
and System.IO.File
namespaces.
So what exactly is the difference between:
My.Computer.FileSystem.CopyFile(source, dest, True)
and:
System.IO.File.Copy(source, dest, True)
Is there a performance difference? What is everyone's opinion on which which has the edge on read-ability? I personally use the My.Computer
Namespace but that is just habit now.
My.* is simply a set of facade-pattern classes implemented for VB.NET that encompass common System.IO* (and other) operations. There is a very tiny performance hit since you're going through an extra layer of abstraction but you have to decide if it's worth optimizing for that. I would suggest using whichever way makes sense to you and others in your shop.
If you examine the code for My.Computer.FileSystem.CopyFile
with .NET Reflector you will see that the method wraps many System.IO classes such as File and Directory and especially the File class' Copy, Move and Delete methods. Snippet:
'lots of other code snipped out for brevity and to show the use of System.IO classes...
Directory.CreateDirectory(FileSystem.GetParentPath(str))
'snip
If
' snip
Else
File.Delete(str)
File.Move(path, str)
End If
Else
File.Move(path, str)
End If
End Sub
Virtually nothing.
My.Computer
was added to VB as a more convenient and understandable abstraction layer to underlying functions. Some of it's methods add new functionality which in my opinion would be the only time you would use it over System.IO.File
.
An example where My.Computer
would add functionality over System.IO.File
is the Network.DownloadFile method, wherein it has the ability to show a dialog to the user:
If showUI is set to True, a dialog box
appears that shows the progress of the
operation; the dialog box contains a
Cancel button that can be used to
cancel the operation. The dialog box
is not modal, and therefore does not
block user input to other windows in
the program.
If you've already used System.IO.File
in places I'd highly recommend against using My.Computer
over it for consistency reasons. Namely, don't go around mixing calls to methods in My.Computer
and System.IO.File
, stick to one namespace!
With regard to the
System.IO.Directory.Delete
and
FileSystem.DeleteDirectory
method, there is quite an important difference.
Using
System.IO.Directory.Delete
a 'System.IO.IOException' will be thrown if the directory isn't empty. However, with
FileSystem.DeleteDirectory
the default action is to go ahead and delete the file unless you include an addidional parameter
This is from this page
Public Shared Sub DeleteDirectory ( directory As String, onDirectoryNotEmpty As DeleteDirectoryOption
)
Parameters directory
Type: System.String Directory to be deleted.
onDirectoryNotEmpty
Type:
Microsoft.VisualBasic.FileIO.DeleteDirectoryOption
Specifies what should be done when a directory that is to be deleted contains files or directories. Default is DeleteDirectoryOption.DeleteAllContents.
The other option is to specify DeleteDirectoryOption.ThrowIfDirectoryNonEmpty
There are also other differences, but this one, to me stands out a mile.
The My
namespace is a VB.Net construct which is intended, in part, to be a bridge between VB6 and .Net APIs. These methods will tend to have VB6 semantics + look and feel.
If you're a VB6 user transitioning to .Net I would use these methods as they will be closer to the behavior you are expecting. Otherwise I would stick with the standard .Net APIs of System.IO.File.Copy
EDIT
Several people have questioned if I'm mistaking the My
namespace for the Microsoft.VisualBasic
namespace. I'm not. The My
namespace is a lot of things but one item it does is wrap certain calls into methods that forward into Microsoft.VisualBasic
. For example if you type the following code into a VB.net project
My.Computer.FileSystem.CopyFile(source, dest)
It will result in the following set of events
- A call to
MyProject.Computer.FileSystem.CopyFile
will be embedded in the application
- The types
MyProject
and MyComputer
will be generated into the assembly
- The
MyComputer
type simply derives from Microsoft.VisualBasic.Devices.Computer
- Hence the
FileSystem.CopyFile
method resolves down to FileSystemProxy.CopyFile
which simply forwards to FileSystem.CopyFile
Here's a difference that caused by app to malfunction:
My.Computer.FileSystem.WriteAllText inserts a 3 byte BOM (EF BB BF) at the beginning of the file, and system.io.file does not.
Thus, I replaced My.Computer.FileSystem.WriteAllText with system.io.file.WriteAllText and that fixed it.