• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 507
  • Last Modified:

Directory.GetFiles and file access?

Hi all,

I'm doing a Directory.GetFiles(strPath, strType) to get a list of files in a directory.

Then I am going through each file to process it. I'm doing that with a

foreach (string file in Files)
{
   do something
}

*NOTE: I'm assigning the files to an array from teh Directory.GetFiles statements.

Now, the problem is IF a file that I'm working with is being access by somebody or something else then the "do something" will fail.

I want to skip that file then all together.

Was I was thinking about doing was before I "do something" I wanted to see about renaming the file to a file with the same name. So something like File.Move(file, file);

Would/should that work or is there another way?

Any information would be greatly appreciated.

Thanks
0
davism
Asked:
davism
  • 6
  • 6
  • 4
2 Solutions
 
Todd GerbertIT ConsultantCommented:
Perhaps you want something like:

foreach (string file in Files)
{
    try
    {
        doSomething(file);
    }
    catch (FileAccessException)
    {
        // Handle the condition where file was locked by someone else
    }
}

Open in new window



Maybe I'm misunderstanding your question though...seems to me of doSomething() would fail, then File.Move would too for the same reason, so I'm not sure what your line of thought is there.
0
 
Todd GerbertIT ConsultantCommented:
Ahh...I think I get it now.  doSomething is a long running process and if somebody else accesses the file after doSomething starts (but before it finishes) you have a problem?

Depending on what exactly constitutes "do something" may simply be able to open the files for exclusive access, thereby preventing any other process from opening them until you've closed'em.
0
 
davismAuthor Commented:
That seems to work BUT I don't want it to throw an exception on that. I want it to continue to the next file.

How would/could I do that?
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Todd GerbertIT ConsultantCommented:
Just leave the catch block empty will cause the loop to simply go-round to the next file.  Exercise caution in doing so though, i.e. make sure you clean up anything that needs to be cleaned up in the catch or finally block (e.g. if you successfully opened the file in the try block, make sure you close it, etc).
0
 
davismAuthor Commented:
tgerbert, yes and no. If there are 5 files in the directory for instance.  None of the files are being access but another process or something except for file #2.

Then what happens is the first of the file files process fine (and the "do something" happens). I hit the second file. "do something" will throw the exception because I cannot do something with that file or in that file (like a read or something) and because something else (another program or user or something) has that file open exclusively; an exception will be thrown on my foreach.

The end result is the 3rd, 4th and 5th files are NOT processed because that exception was thrown on the 2nd file.

that's what I'm trying to solve. The File.Move actually throws the exception because the file has exclusive access. I wanted to see about the file move to identify that it's in process (or exclusively access) but I'm not sure how to do that in C#.

Make sense?
0
 
davismAuthor Commented:
Maybe I just missed that...tgerbert, you're saying to just left the catch blank? I am not following what you're getting at there.
0
 
Carlos VillegasFull Stack .NET DeveloperCommented:
tgerbert solution works buddy, that is the way
0
 
Carlos VillegasFull Stack .NET DeveloperCommented:
foreach (string file in Files)
{
    try
    {
        doSomething(file);
        File.Move // MUST BE HERE
    }
    catch (FileAccessException)
    {
        // LEAVE EMPTY
    }
}
0
 
Todd GerbertIT ConsultantCommented:
Yes, leave the catch block empty is the basic idea, but there are some caveats. Gimme a few minutes & I'll try to get you a  better example.
0
 
davismAuthor Commented:
yv989c.

Actually it didn't. The FileAccessException is an available exception when I am using System.IO; There is an IOException.

But when I do something like this:

try
{
                string[] files = Directory.GetFiles("C:\\", "*.*");

                foreach (string file in files)
                {

                    objFileout = new System.IO.StreamWriter("C:\\Test.txt");
                    File.Move(file, file);
                }
}
catch (IOException ex) //being that FileAccessException wasn't available
{
}

What am I missing there?
0
 
davismAuthor Commented:
Or it is that I have the try and catch outside of that foreach?
0
 
davismAuthor Commented:
Yep...that was it. :-) DUH!
0
 
Carlos VillegasFull Stack .NET DeveloperCommented:
Yes that is, try:
        string[] files = Directory.GetFiles("C:\\", "*.*");
        foreach (string file in files)
        {
            try
            {
                objFileout = new System.IO.StreamWriter("C:\\Test.txt");
                File.Move(file, file);
            }
            catch (IOException ex) //being that FileAccessException wasn't available
            {
            }
        }

Open in new window

0
 
Carlos VillegasFull Stack .NET DeveloperCommented:
Was clear in the tgerbert example
0
 
Todd GerbertIT ConsultantCommented:
See my first comment, note that try/catch is inside the foreach loop.

If you step through your current code a line at a time you might see why it behaves the way it does.

After an exception is thrown, execution resumes after the try block.
0
 
Todd GerbertIT ConsultantCommented:
This example is a little silly, but I just wanted to show how you don't necessarily always want a completely empty catch block, and how there's still sometimes some cleanup that needs to be done even when you can recover from an exception.

Note that you can have more than one catch block, and the first one that the runtime finds with a matching exception type is what runs...so they should be listed in order of least-specific to most-specific.

using System;
using System.IO;

class Program
{
	static void Main(string[] args)
	{
		string strPath = "C:\\temp";
		string strType = "*.txt";

		string[] files = Directory.GetFiles(strPath, strType);

		foreach (string file in files)
		{
			FileStream openedFile = null;
			try
			{
				openedFile = File.Open(file, FileMode.Open);

				SomethingNotFileRelated();

				try
				{
					DoSomething(openedFile);
				}
				catch (Exception ex)
				{
					Console.WriteLine("DoSomething() threw an exception: " + ex.Message);
					Console.Write("Press any key to proceed to the next file...");
					Console.ReadKey();
				}
			}
			catch (IOException ex)
			{
				// This block will catch only IOExceptions thrown
				// EXCEPT exceptions
				// that are handled by the inner try/catch lines,
				// That means this catch block (in THIS example) will
				// only ever catch exceptions thrown by the File.Open
				System.Diagnostics.Debug.WriteLine(
					"File: " + file + ", exception: " + ex.Message + ", proceeding to next file.");
			}
			catch (Exception ex)
			{
				// This catch block will catch any other exceptions
				Console.WriteLine("An unexpected exception was thrown: " + ex.Message);
				Console.Write("Press 'Y' to attempt to continue. ");
				ConsoleKey c = Console.ReadKey().Key;
				if (c != ConsoleKey.Y)
					Environment.Exit(1);
			}
			finally
			{
				// Since it's possible the file open might have succeeded,
				// even if an exception was thrown, it's important
				// to have this finally block
				if (openedFile != null)
				{
					openedFile.Dispose();
					openedFile = null;
				}
			}
		}
	}

	static void DoSomething(FileStream fstream)
	{
		// This method doesn't actually do anything
		// except throw an exception (just for demonstration's sake)
		if (random.Next(0, 2) == 1)
			throw new Exception("DoSomething(): Test Exception Thrown");

		Console.WriteLine("DoSomething() finished successfully.");
	}

	static void SomethingNotFileRelated()
	{
		if (random.Next(0, 2) == 1)
			throw new Exception("NotFileRelated: Test Exception");

		Console.WriteLine("SomethingNotFileRelated() finished successfully.");
	}

	static Random random = new Random();
}

Open in new window

0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 6
  • 6
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now