c# failed to check existed file in directory - c#

there are nothing is inside my test002 folder, by right my output should be is "nothing is inside the folder",but after compile there are nothing prompt.
what i want to do is if there are any .doc file is inside my folder, just upload it
if there are nothing is inside the folder, ask user to upload .doc to required folder.
protected void Button3_Click(object sender, EventArgs e)
{
try
{
string[] chkUserResume = Directory.GetFiles(HttpContext.Current.Server.MapPath(#"~/Enduser/test002/"), "*.doc");
if (chkUserResume!=null)
{
foreach (string name in chkUserResume)
{
Response.Write(name + " is exist");
}
}
else
{
Response.Write("nothing is inside the folder");
}
}
catch (Exception ex)
{
Response.Write(ex.Message.ToString());
}
}

The null keyword means that the variable is not set to any real value, which is different from an empty array.
In this case, chkUserResume will never be null, it will be an empty array. You should check that chkUserResume.Length is 0 instead.

You're not checking that chkUserResume is empty:
if (chkUserResume.Length == 0)
{
Response.Write("nothing is inside the folder");
}
else
{
foreach (string name in chkUserResume)
{
Response.Write(name + " is exist");
}
}
However as chkUserResume will never be null there's no need to check for that.

Related

How can i get all files on disk with a specific extension using 'Directory.getFiles' and save them in a list

I'm doing a console project whose goal is to search the entire disk for all files with the extension '.config'
I've tried something like:
foreach (string file in Directory.GetFiles("C:\\", "*.config", SearchOption.AllDirectories))
{
Console.WriteLine(file);
Console.ReadLine();
}
but gave me an error "denied access to path (...)".
On the internet I found this code:
Stack<string> pending = new Stack<string>();
pending.Push("C:\\");
while (pending.Count != 0)
{
var path = pending.Pop();
string[] next = null;
try
{
next = Directory.GetFiles(path, "*.config");
}
catch { }
if (next != null && next.Length != 0)
foreach (var file in next)
{
Console.WriteLine(file);
Console.ReadLine();
}
try
{
next = Directory.GetDirectories(path);
foreach (var subdir in next) pending.Push(subdir);
}
catch { }
}
but it just shows the path clicking always in 'enter' and I want to save those files/path in a list.
Someone can help?
There are two things you can do to improve that code:
Use Directory.EnumerateFiles() and Directory.EnumerateDirectories() to avoid making a copy of the names of all the files in each directory.
Make the return type of the method IEnumerable<string> to make it easier to consume.
We also need to be very careful about exceptions caused by attempting to access protected files and directories. The code below is also complicated by the fact that you're not allowed to yield return from inside a try/catch block, so we have to rearrange the code somewhat.
(Also note that we have to dispose the enumerator returned from .GetEnumerator(); normally this is done automatically when you use foreach, but in this case we can't - because of having to avoid doing yield return in a try/catch - so we have to use using to dispose it.)
Here's a modification of your original code to do this:
public static IEnumerable<string> GetFiles(string root, string spec)
{
var pending = new Stack<string>(new []{root});
while (pending.Count > 0)
{
var path = pending.Pop();
IEnumerator<string> fileIterator = null;
try
{
fileIterator = Directory.EnumerateFiles(path, spec).GetEnumerator();
}
catch {}
if (fileIterator != null)
{
using (fileIterator)
{
while (true)
{
try
{
if (!fileIterator.MoveNext()) // Throws if file is not accessible.
break;
}
catch { break; }
yield return fileIterator.Current;
}
}
}
IEnumerator<string> dirIterator = null;
try
{
dirIterator = Directory.EnumerateDirectories(path).GetEnumerator();
}
catch {}
if (dirIterator != null)
{
using (dirIterator)
{
while (true)
{
try
{
if (!dirIterator.MoveNext()) // Throws if directory is not accessible.
break;
}
catch { break; }
pending.Push(dirIterator.Current);
}
}
}
}
}
As an example, here's how you could use a console app to list all the accessible ".txt" files on the "C:\" drive:
static void Main()
{
foreach (var file in GetFiles("C:\\", "*.txt"))
{
Console.WriteLine(file);
}
}
Replace the lines
Console.WriteLine(file);
Console.ReadLine();
with a method to store them in a list.
For example
foundFiles.Add(file);
Then when the method is done, you can read all found file paths from this list.
Notes:
This will not yield all files on the system that match the filter.
Only files where your application has access to their respective directory are found this way.
For example the Windows directory and user directories of other users are usually protected. (assuming you run on Windows)
Keep in mind, that some files might be protected independently of their directory.
So when trying to read them, also consider the fact, that the read might fail.
Just encompass the read with a try catch.
Regarding the error "denied access to path (...)", sometimes you have to run Visual Studio as an a administrator in order to access some folders in the C:\ drive.

SSIS Script Task Check if a folder is empty

Within a SSIS Script Task, I have the below code that checks if a folder is empty. I then want to pass if it is or not into the variable 'Dim_File_Count' and use a Precedence constraint to move onto the next task if successful. However my code keeps stating the folder is empty, even when it's not:
public void Main()
{
//string FolderName = Dts.Variables["User::Tech_Dim"].Value.ToString();
if (File.Exists(Dts.Variables["User::Tech_Dim"].Value.ToString())==false)
{
Dts.Variables["User::Dim_File_Count"].Value = 0;
MessageBox.Show("folder empty");
}
else
{
Dts.Variables["User::Dim_File_Count"].Value = 1;
MessageBox.Show("folder is not empty");
}
Dts.TaskResult = (int)ScriptResults.Success;
}
You can use the Length property of the GetFiles method of the Directory class to check if there are any files in the specified folder. The optional third SearchOption parameter of GetFiles can be used if searching sub-directories is necessary, i.e. SearchOption.AllDirectories, with the default checking only the parent folder.
if (Directory.GetFiles(Dts.Variables["User::Tech_Dim"].Value.ToString(), "*").Length > 0)
{
Dts.Variables["User::Dim_File_Count"].Value = 0;
MessageBox.Show("folder empty");
}
else
{
Dts.Variables["User::Dim_File_Count"].Value = 1;
MessageBox.Show("folder is not empty");
}

File.Exists + File.Move Erroring "The process cannot access the file because it is being used by another process."

I have what I thought would be a very simple file mover script. It checks for a file and moves it to a new directory if it exists:
if (File.Exists(_collection[x,0]))
{
System.IO.File.Move(_collection[x, 0], _moveTo);
MessageBox.Show("File moved because it was stale.");
}
It passes the check that the file exists, but then errors on the following line when trying to move it stating that the file is being used by another process. I can only assume that File.Exists is causing it to hang up somehow, but can't find a solution from anyone else who had this problem.
try this code:
string filePathNameToMove = "";
string directoryPathToMove = "";
if (File.Exists(filePathNameToMove))
{
string destinationFilePathName =
Path.Combine(directoryPathToMove, Path.GetFileName(filePathNameToMove));
if (!File.Exists(destinationFilePathName))
{
try
{
File.Move(filePathNameToMove, destinationFilePathName);
Console.WriteLine("File Moved!");
}
catch (Exception e)
{
Console.WriteLine("File Not Moved! Error:" + e.Message);
}
}
}
In case anyone else has this problem. In my case, the file had been opened in Excel and Excel was never garbage collected after being terminated. So the OS still thought the file was being accessed. I did the following, crude, but it works.
for (int i = 1; i > 0; i++)
{
try
{
File.Move(sourceFileName, destinationFileName);
break;
} catch
{
GC.Collect();
}
}

Check if can create folder/file in specific path

I need to check if the current user has write permissions inside the path. Here an example:
string save_path = #"C:\Windows\somefolder";
string my_dir = Path.DirectorySeparatorChar + "foobar";
//check if specific path are valid
if (!Directory.Exists(save_path)) { return; }
if (Directory.Exists(save_path + my_dir)) { return; }
if (canWriteOnPath(save_path)) {
Directory.CreateDirectory(save_path + my_dir);
} else {
//You are not allowed to save here OR not are launching this application as "administrator"
Directory.CreateDirectory(#"C:\Users\contoso\Documents\foobar");
}
solved in this question:
CurrentUserSecurity cus = new CurrentUserSecurity();
bool flag = cus.HasAccess(new DirectoryInfo(#"C:\Windows"), FileSystemRights.Write);
if (flag) {
//yes create that folder
Directory.CreateDirectory(Path.Combine(save_path, my_dir));
} else {
//NO YOU CANT
Directory.CreateDirectory(#"C:\Users\contoso\Documents\foobar");
}
The robust method would be to Try to create the directory and Catch any resulting exception.
The documentation for Directory.CreateDirectory lists the possible exceptions: IOException, UnauthorizedAccessException, ArgumentException, ArgumentNullException, PathTooLongException, DirectoryNotFoundException.
Although unlikely, it is possible that the permissions changed between your code checking that access is allowed and actually trying to create the directory.

How to delete files while Traversing folder tree

I am not sure if I am doing this correctly or if my logic is correct.
I am trying to go down a folder structure delete files older than a certain number of days, this part I have correctly implemented, delete empty folders.
Can all this be done in one loop?
Where do I do the folder delete?
I want to delete empty folders up to 3 or 4 level down.
private static void TraverseTree(System.IO.DirectoryInfo folder, double days)
{
Stack<string> dirs = new Stack<string>();
if (!folder.Exists)
throw new ArgumentException();
dirs.Push(folder.FullName);
while (dirs.Count > 0)
{
string currentDir = dirs.Pop();
string[] subDirs;
try
{
subDirs = System.IO.Directory.GetDirectories(currentDir);
}
// An UnauthorizedAccessException exception will be thrown if we do not have
// discovery permission on a folder or file. It may or may not be acceptable
// to ignore the exception and continue enumerating the remaining files and
// folders. It is also possible (but unlikely) that a DirectoryNotFound exception
// will be raised. This will happen if currentDir has been deleted by
// another application or thread after our call to Directory.Exists. The
// choice of which exceptions to catch depends entirely on the specific task
// you are intending to perform and also on how much you know with certainty
// about the systems on which this code will run.
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
continue;
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
continue;
}
string[] files = null;
try
{
files = System.IO.Directory.GetFiles(currentDir);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
continue;
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
continue;
}
// Perform the required action on each file here.
// Modify this block to perform your required task.
foreach (string file in files)
{
try
{
// Perform whatever action is required in your scenario.
System.IO.FileInfo fi = new System.IO.FileInfo(file);
Console.WriteLine("{0}: {1}, {2}", fi.Name, fi.Length, fi.CreationTime);
// Delete old files
if (fi.LastWriteTime < DateTime.Now.AddDays(-days))
fi.Delete();
}
catch (System.IO.FileNotFoundException e)
{
// If file was deleted by a separate application
// or thread since the call to TraverseTree()
// then just continue.
Console.WriteLine(e.Message);
continue;
}
}
// Push the subdirectories onto the stack for traversal.
// This could also be done before handing the files.
foreach (string str in subDirs)
dirs.Push(str);
}
}
Code is from MSDN.
A recursive approach would probably be cleaner.
private static void DeleteOldFilesAndFolders(string path)
{
foreach (string directory in System.IO.Directory.GetDirectories(path))
{
DeleteOldFilesAndFolders(directory);
// If the directory is empty and old, delete it here.
}
foreach (string file in System.IO.Directory.GetFiles(path))
{
// Check the file's age and delete it if it's old.
}
}
Something that I notice about your code is that the dozens of lines of "mechanism" for walking the tree structure completely overwhelms the two lines of code that actually do the work. That makes it hard to read, understand, change, debug and maintain this code.
Here's what I would do instead.
You have only three high-level operations in your program: (1) get all the files, (2) filter to find the ones to delete, (3) delete each file. So write a program which does each of those in one statement.
For the first operation, I would factor out the mechanism above into its own function: a function which implements, say, IEnumerable, and all it does is keeps on yielding out information about files. It doesn't do anything with them; its only purpose is to keep spitting out file infos.
Once you have that mechanism then you can start writing queries on top of that sequence to attain the second operation. The third operation then follows directly from the second.
In short, the main line of your program should look something like this:
var allFiles = TraverseFolder(folder);
var filesToDelete = from file in allFiles where IsOld(file) select file;
foreach(var fileToDelete in filesToDelete) Delete(fileToDelete);
Is that clear?
There is almost the same question here:
How to delete all files and folders in a directory?
This is delete by name, but you could check other properties.
Here is a more general solution to the problem which gives you a file system walker implemented non-recursively as IEnumerable.
for which your solution can probably be implemented as:
List<string> directoriesToDelete = new List<string>();
DirectoryWalker walker = new DirectoryWalker(#"C:\pathToSource\src",
dir => {
if (Directory.GetFileSystemEntries(dir).Length == 0) {
directoriesToDelete.Add(dir);
return false;
}
return true;
},
file => {
if (FileIsTooOld(file)) {
return true;
}
return false;
}
);
foreach (string file in walker)
File.Delete(file);
foreach (string dir in directoriesToDelete)
Directory.Delete(dir);
I enhanced John's solution, implementing missing code, error handling and checks:
/* Given a directory path and a datetime,
* recursively delete all files and directories contained in such directory
* (given directory included) that are younger than the given date.
*/
private bool DeleteDirectoryTree(string dir, DateTime keepFilesYoungerThan)
{
//checks
if (String.IsNullOrEmpty(dir) || !Directory.Exists(dir))
return false;
//recurse on children directories
foreach (string childDir in Directory.GetDirectories(dir))
DeleteDirectoryTree(childDir, keepFilesYoungerThan);
//loop on children files
foreach (string file in Directory.GetFiles(dir))
{
//calculate file datetime
DateTime fileDT = new DateTime(Math.Max(File.GetCreationTime(file).Ticks, File.GetLastWriteTime(file).Ticks));
//if file is old, delete it
if (fileDT <= keepFilesYoungerThan)
try
{
File.Delete(file);
Log("Deleted file " + file);
}
catch (Exception e)
{
LogError("Could not delete file " + file + ", cause: " + e.Message);
}
}
//if this directory is empty, delete it
if (!Directory.EnumerateFileSystemEntries(dir).Any())
try
{
Directory.Delete(dir);
Log("Deleted directory " + dir);
}
catch (Exception e)
{
LogError("Could not delete directory " + dir + ", cause: " + e.Message);
}
return true;
}

Categories