Are they equivalent or alternatives to each other? Is any of them deprecated and if so, which one? Which one is recommended for use in an ASP.NET web application? My aim is to extract all files from a specific directory recursively.
Directory is a static class that provides static methods for working with directories. DirectoryInfo is an instance of a class that provides information about a specific directory. So for example, if you wanted the information about C:\Temp:
var dirInfo = new DirectoryInfo("C:\\Temp");
if (dirInfo.Exists) {
FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
...
}
If you just wanted the names as strings, it might be quicker and easier to avoid creating an instance of DirectoryInfo by using the static methods of Directory.
if (Directory.Exists("C:\\Temp")) {
string[] files = Directory.GetFiles("C:\\Temp", "*.*", SearchOption.AllDirectories);
...
}
In short, it really doesn't matter which you use as long as it does what you want. Neither is recommended over the other.
Directory class is a static
class which can be used to create,
move, enumerate directories and sub
directories. The DirectoryInfo
class is also served for the same
purpose like Directory class where
its members are instance members as
opposed to Directory class. The main
difference between the two lies in
when we can use these classes.
Directory class can be used when we
want to a simple folder operation at
once. For example, you need to delete
the folder and get away. But, the
DirectoryInfo class is associated
with a folder and provides you all the
operations that can be done on the
folder. The DirectoryInfo class
accepts a path as parameter when
instantiating and provides you
everything on the folder. You can
create subdirectories, move, enumerate
etc. CODEDIGEST
Also an important note if you have to do several actions on directory DirectoryInfo will have performance advantage as it will not require security privileges check on each action.
Directory
Directory is a static class.
This should be used when we want to perform one operation in the folder.
As There is not any requirement to create object for Directory class, so not any overhead for using this.
Directory Info Class
DirectoryInfo is not a static class.
If user is required to perform lot of operations on one directory like creation, deletion, file listing etc, then DirectoryInfo class should be used.
A separate object is created for performing all directory related operations.
It's effective if you are going to perform many operations on the folder because, once the object is created, it has all the necessary information about the folder such as its creation time, last access time and attributes. All the members of the DirectoryInfo class are instance members.
DirectoryInfo is (basically) the Directory class but is used in a non-static context. If you are going to be making many calls to the FileSystem, especially when its the same folder or in subdirectory of said folder, MSDN suggests using DirectoryInfo.
DirectoryInfo has a DirectoryInfo.GetFiles method that probably meet your requirements.
Related
How can I use (to avoid PathTooLongException):
System.IO.FileInfo
with paths bigger than 260 chars?
Are there similar classes/methods that return the same result of FileInfo class?
From what I know it is not easily possible. While it is possible to use workaround for streams as phoenix mentioned, it is not possible for file names handling. Internally every class that works with file names perform checks for long file names.
You can instantiate FileInfo and fill private memebers using reflection (however this is not recommended) and get FileInfo pointing to file with long path. But when you try to use this object you will still receive PathTooLongException exceptions, because for example, Path class (used heavily by FileInfo) checks for long path on every method call.
So, there is only one right way to get problem free long path support - implement your own set of classes that will mimic FileInfo behavior. It is not very complex (only security maybe), but time-consuming.
Update: Here even two ready solutions for this problem: AlpfaFS and Zeta Long Paths
Here at work we deal with long paths quite frequently, and we therefore had to basically roll our own System.IO to do it. Well not really, but we rewrote File, Directory, FileInfo, DirectoryInfo and Path just to name a few. The basic premise is that it's all possible from a Win32 API perspective, so all you really need to do at the end of the day is invoke the Unicode versions of the Win32 API functions, and then you're good. It's alot of work, and can be a pain in the ass at times, but there's really no better way to do it.
There's a great library on Microsoft TechNet for overcoming the long filenames problem, it's called
Delimon.Win32.IO Library (V4.0) and it has its own versions of key methods from System.IO
For example, you would replace:
System.IO.Directory.GetFiles
with
Delimon.Win32.IO.Directory.GetFiles
which will let you handle long files and folders.
From the website:
Delimon.Win32.IO replaces basic file functions of System.IO and
supports File & Folder names up to up to 32,767 Characters.
This Library is written on .NET Framework 4.0 and can be used either
on x86 & x64 systems. The File & Folder limitations of the standard
System.IO namespace can work with files that have 260 characters in a
filename and 240 characters in a folder name (MAX_PATH is usually
configured as 260 characters). Typically you run into the
System.IO.PathTooLongException Error with the Standard .NET Library.
I only needed to use the FullName property but was also receiving the PathTooLongException.
Using reflection to extract the FullPath value was enough to solve my problem:
private static string GetFullPath(FileInfo src)
{
return (string)src.GetType()
.GetField("FullPath", BindingFlags.Instance|BindingFlags.NonPublic)
.GetValue(src);
}
Why there are two class for the almost same purpose System.IO.File and System.IO.FileInfo.
System.IO.File provides static members related to working with files, whereas System.IO.FileInfo represents a specific file and contains non-static members for working with that file.
From MSDN:
Because all File methods are static,
it might be more efficient to use a
File method rather than a
corresponding FileInfo instance method
if you want to perform only one
action. All File methods require the
path to the file that you are
manipulating.
The static methods of the File class
perform security checks on all
methods. If you are going to reuse an
object several times, consider using
the corresponding instance method of
FileInfo instead, because the security
check will not always be necessary.
In general they do two very different things:
System.IO.File - getting/working with any file
System.IO.FileInto - getting/working with (including metadata) a particular file
Granted they do share a few methods with the same purpose, but for the most part they have very different purposes/scenarios that they serve best.
I've been reading that the static methods of the File Class are better used to perform small and few tasks on a file like checking to see if it exists and that we should use an instance of the FileInfo Class if we are going to perform many operations on a specific file.
I understand this and can simply use it that way blindly, but I would like to know why is there a difference?
What is it about the way they work that make them suitable for different situations? What is the point of having this two different classes that seem do the same in different ways?
It would be helpful if someone could answer at least one of this questions.
Generally if you are performing a single operation on a file, use the File class. If you are performing multiple operations on the same file, use FileInfo.
The reason to do it this way is because of the security checking done when accessing a file. When you create an instance of FileInfo, the check is only performed once. However, each time you use a static File method the check is performed.
The methods of the File and FileInfo classes are similar, but they differ in that the methods of the File class are static, so you need to pass more parameters than you would for the methods of the FileInfo instance.
You need to do this because it operates on a specific file; for example, the FileInfo.CopyTo() method takes one parameter for the destination path that's used to copy the file, whereas the File.Copy() method takes two parameters for the source path and the destination path."
References
http://aspfree.com/c/a/C-Sharp/A-Look-at-C-Sharp-File-and-FileInfo-Classes/1/
http://intelliott.com/blog/PermaLink,guid,ce9edbdb-6484-47cd-a5d6-63335adae02b.aspx
The File.Exists will perform much faster than a new FileInfo(filePath).Exists - especially over a network and provided the files actually exist. This is because File.Exists will only check for existence of the file, whereas a new FileInfo(filePath).Exists first constructs a FileInfo object, which contains all the properties (dates, size etc) of the file (if it exists).
In my experience with this, even checking for the existence of 10 files over the network is noticeably faster (ie 20ms vs 200ms) by using File.Exists.
File is optimized for one-off operations on a file, FileInfo is optimized around multiple operations on the same file, but in general there isn't that much difference between the different method implementations.
If you want to compare the exact implementations, Use Reflector to look at both classes.
A FileInfo may be needed to deal with Access Control properties. For the rest it is a Static versus Instance choice and you can pick what is convenient.
FileInfo is an instance of a file thus representing the file itself. File is a utility class so can work with any file
FileInfo:
Need to instantiate before using
Contains instance methods
Cache Info about the File and you need to call Refresh every time to get the latest info about the File
File:
No need to instantiate
Contains static methods
Do not cache, so you get latest info every time you use it.
src:
FileInfo
File
Yes, and one of the reason could be is, as Nag said Files is a utility class and hence no instance is required to be created. Same time, as File being utility class, each time require security check.
On other hand FileInfo requires instance to be created, and that point it uses security check. Thus, now performing multiple operation using FileInfo will not invoke security checks.
Recently I faced problem with File.Exist, I hate this function. After than I've used Fileinfo class Exist function then my program works correct.
Actually what happen in development enviornment File.Exist works well but when it goes to live environment this function is blocking the file object due to that reason I am getting the error access denied and not able to use the file.
This is my learning.
I will never used File.Exist method best is to create the object and then use it. Be aware to use static methods.
The major difference between File class and FileInfo class is that
Both members of the File and FileInfo class are decorated with the [System.Security.SecurityCritical] and [System.Security.SecuritySafeCritical] attribute but File class has 'multiple security checks' as compared to FileInfo class (Read Here) and the check is performed each time when you call a static member of the File class.
When you create an instance of FileInfo, the check is performed only once.
Apart from these, other minor differences are that File is a static type class whereas FileInfo is an instance type class.
Therefore to access the members of FileInfo class you need to create an instance whereas in File class you can directly access its members without the need to create an instance.
If you are performing multiple operations on the same file, it can be more efficient to use FileInfo instance methods instead of the corresponding static methods of the File class.
However, File class provides more methods as compared to FileInfo class.
Note: Either the SecurityCriticalAttribute attribute or the SecuritySafeCriticalAttribute attribute must be applied to code for the code to perform security-critical operations.
I have an asp.net mvc project that uses some search methods in a seperate library.
This library needs to know the location of my lucene index files.
private static string lucenePath = ConfigurationManager.AppSettings["lucenePath"];
public static ColorList SearchColors(Query query) {
return new ColorList(
new IndexSearcher(Path.GetFullPath(lucenePath)),
query);
}
This correctly reads my configured lucenePath from the web.config's application key node.
But how can I get the correct full path from this relative path? Path.GetFullPath gives me a completely incorrect path.
--Conclusion--
If you want to go full-out, tvanfosson's answer is probably for you.
I, however, kept it a little more brain dead by using the following:
Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
ConfigurationManager.AppSettings["luceneIndex"].TrimStart('\\'));
This will look in the caller's app.config for an appkey called "path" and combine its value to the caller's path. The TrimStart() makes sure that the config file can both contain a leading \ or not.
Server.MapPath(string);
Since you are referencing this from a separate library, you might have to jump through a bunch of hoops to get access to the HttpServerUtitity or introduce some coupling to classes that are difficult to mock. You might want to consider having a single configuration class that loads properties from the web configuration that gets injected into your library via constructor/setter. To make it easier to test against, you could define an interface that could be mocked in your unit tests and have it implement that. The configuration class could use the HttpServerUtility to obtain the absolute path and store it internally to be reused.
I am reorganizing my source files into a single solution with a single project, due to various reasons:
a paranoic configured antivirus software;
Advices on partitioning code through .NET assemblies
Control component dependencies to gain clean architecture
Benefit from the C# and VB.NET compilers perf
This leaves me with many namespaces, which are splitted across multiple files. So far, I am using this convention: given the namespace Company.Project.A, the files are named A.f1.cs, A.f2.cs and so on, and the Company.Project.B namespace is splitted across B.f1.cs, B.f2.cs, etc.
Given the single project restriction, are there any better ways to organize multiple files in multiple namespaces?
Yes - use folders.
If you create a folder within a project, new classes within that folder will automatically use the folder name as the basis for the namespace.
For instance, if you have a project with a default namespace of "Company.Project" and a folder "Foo" containing "Bar.cs" you'll end up with:
using System; // Etc
namespace Company.Project.Foo
{
class Bar
{
}
}
So the solution is right here. It's Folders. But it's sometimes tricky. First of all it's kind of a good idea to have one file per class. If you will pack several classes into one file - you'll have problems with finding them with time.
Second thing about folders - if you will click on a folder and choose for example "Add -> New Item", this item will be put into selected folder. But watch out! If you will move files between folders, namespaces are not updated.
It's common source of messing project. Just after a while you can end up with a project where you have neat organized folder and files, but not reflecting namespaces. So for example, if you have class MyClass in folder MyFolder make sure, your namespace for this class is something like MyApp.MyFolder and not some old rubbish.
So If you will not pack classes into one file and watch if classes namespaces reflect folder hierarchy - you're on the good road to make you project very easy to read and navigate.
100% agree with Jon Skeet.
To gain more overview at the folder level we're creating folders breaking the namespace structure by prefixing them with an underscore.