Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

first off here's the code

#region Declarations
	FileSystemWatcher _watcher = new FileSystemWatcher("C:\\" ,"*.pgn");

	#endregion
	
	private void frmMain_Load(object sender, System.EventArgs e)
	{
	_watcher.IncludeSubdirectories = true;
	_watcher.EnableRaisingEvents = true;
				
	}

	private void _watcher_Created(object sender, System.IO.FileSystemEventArgs e)
	{ 
		StreamReader sr;
		StreamWriter sw;
		try
		{
			sr = new StreamReader(e.FullPath);
			sw = new StreamWriter("AutoCompiledChessGames",true);
			
			while (sr.Peek() != -1)
			{
				sw.WriteLine(sr.ReadLine());
			}
			sr.Close();
			sw.Close();

		}
		catch (Exception err)
		{
			MessageBox.Show(err.Message);
		}

	}

 

When this code is run and a .pgn file is created the _watcher_Created event fires twice (that's expected)

i can get around that fairly easily...

my problem though is that i get different exceptions thrown when i run this method.

Sometimes i will get "FileNotFoundException"

and sometimes i will get "This file is in use by another program"

(Note a step through in the debugger works though; although it does call the event twice so my file is written twice.)

 

it seems as if with the FileNotFoundException that the watcher is doing it's job so well that the file isn't actually created yet when the event fires.

 

The second seems to be that the file is in the process of being written to so therefore cannot be accessed.

 

My question is... How can i ensure that the file is ready to be read by my program. So that i can write it's data to my file.

 

Is there a method that checks for a files status?

 

looks like i'm hitting the books on this one

i hope someone has some info for me

 

thanks

brandon

i'm not lazy i'm just resting before i get tired.
Posted

using System;
using System.Threading;
using System.IO;

namespace ConsoleApplication1
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
	/// <summary>
	/// The main entry point for the application.
	/// </summary>
	[sTAThread]
	static void Main(string[] args)
	{
		string filename = @"C:\somefile.tmp";
		//see if the file can be read, if not, sleep the thread for 30 sec.
		while(!CanReadFile(filename))
			Thread.Sleep(30000);
		//open the file 2 read
		TextReader text = File.OpenText(filename);
	
		//open the file 2 write
		StreamWriter sw = new StreamWriter("AutoCompiledChessGames.mcg", true);
		//write all the lines in readFile
		sw.Write(text.ReadToEnd());
		//flush the buffer, always important when writing.
		sw.Flush();

		//close the streams
		sw.Close();			
		text.Close();
	}

	/// <summary>
	/// Determines if a <see cref="FileStream"/> can be created with read-only access.
	/// </summary>
	/// <param name="filename">The path of the filename to open.</param>
	/// <returns>true if a read-only <see cref="FileStream"/> can be created using the specified filename.</returns>
	/// <remarks><see cref="FileStream.Close"/> can throw an <see cref="IOException"/>. This exception
	/// will be caught but not handled and the <see cref="FileStream"/>.</remarks>
	static bool CanReadFile(string filename)
	{
		try
		{
			File.OpenRead(filename).Close();
		}
		catch
		{
			return false;
		}
		return true;
	}
}
}

 

If the remarks for CanReadFile bother, it can be easily modified so Close() will throw an exception and let the caller deal w/ it.

Posted

well what i found was that a change event occurs as well and calling my method during the change even worked fine.

It turns out nullifying the 'double' call to the Created and Changed method is harder than i thought...

i've considered some ways of dealing with it but all have a bug somewhere... is there a fool proof way of canceling the extra create and changed events?

 

i'd like to learn the basics of threading... where should i start?

thanks for the code that alone teaches me some about threading

 

brandon

i'm not lazy i'm just resting before i get tired.
Posted

The final goal is to have the FileSystemWatcher find new chess games and from it's methods add those games to a database (for now a text file is my temporary database).

When a new chess game created... the created and changed events are both called twice... i'd like to stop that or at least make sure that i'm not being redundant with my file access.

 

thanks

brandon

i'm not lazy i'm just resting before i get tired.
Posted

I think the only event you need to listen for is the FileSystemWatcher.Created event. If that event is still being raised twice for the same file, you'll need to work around that.

 

I option is to maybe use an Array to store ackonwledged created file paths so that way when the Created event gets raised, you'll know if it's a dupe event. When your done processing the file, just remove the file path from the Array.

 

There are other ways though, depends on what you plan to do with the file in the future.

 

I've only used the FileSystemWatcher in a project once. FOrtunately, I've didn't have the Created event raised multiple times for the same file. The docs state that this can happen though. I was using it on win2k server.

Posted

yes i've considered many ways of nullifying the extra event. The problem is i can not simply just use a string to see if it's the same file being used each time because the file might be edited twice in a row legitimatly.

i've considered using the filename and the LastAccessTime or LastWriteTime property of a file. but even then i'm assuming that a file is never accessed or written too twice in the same minute. That's as fool proof as i can think to get it.

 

There is a thing called Lightning chess and it is quite popular among players. Lightning chess games are usually less than 2 minutes long. Making it very possible to lose in less than a minute.

If a game like that was played immediatly after any other game and the program being used Appended a file each time a game was completed. Then the game would not be recorded.

 

My third idea to help kill that bug was to use the size of a file as a determining factor. The problem is i can't find a way to determine the file size (i'm embarassed to say that one).

 

The only assumption with that idea is. A user edited the file manually, saved it, immeditatly saw the mistake and corrects it in a way that the file size does not change.

If that situation happens in less than a minute once again the edit is missed.

So i'll need a third stipulation to completly verify everything... but now i'm out of ideas besides completly checking every line of the file. Which is a very bad idea in this case because files can contain thousands of chess games at once.

 

In case you've forgotten the Questions are HOW DO I RETRIVE THE FILE SIZE?

WHAT ELSE CAN I CHECK TO MAKE IT FOOL PROOF?

 

What's a chess nerd to do?

brandon

 

 

sorry it's so long of a post... just decided to break down what's going on to the fullest

i'm not lazy i'm just resting before i get tired.
Posted

ohh i thought that was the length of the filename whoops...

can you think of any other ideas that would make this work flawless?

i'm not lazy i'm just resting before i get tired.
Posted
I would still use the array, just manage it differently like, maybe just have the filepath added to the array (allow duplicate filepaths in the array) when events get raised and have a seperate thread process the files in the array. or maybe, when adding a filepath to the array, if the filepath already exists, remove it from the array and add the removed filepath to the end of the array.
Posted

that's my whole issue... reduce redundancy while keeping

accuracy

 

files can be thousands of lines if i check it twice i would be wasting a lot of time and resources

 

can i implement the checksum of a file to see if it has changed from the last time it was caught by filesystemwatcher?

 

i never thought this would be so difficult

 

thanks for the help

brandon

i'm not lazy i'm just resting before i get tired.
Posted (edited)

Don't allow duplicate filepaths in the array. Problem solved!

 

 

Well, when I think about it later... not really. give me a few min

Edited by HJB417
Posted

problem not solved.. because if the same file is edited twice in a row it will be ignored...

 

nice try though

thanks

brandon

i'm not lazy i'm just resting before i get tired.
Posted

Tell me this. The created event gets raised

What methods listen on this event, and what do they do?

 

My guess is you have aMethod Foo that

1) Open the 'created' file

2) read some data from the file

3) close the file

4) write some data to a db

 

 

What is the file format for the chess games?

Can you get all of the chess games in a file?

 

I'm still trying to think of a way to handle this properly

 

Also, what does the created event signify? That a game has been added to the file?

Posted

ok the created event is called, but sometimes is not ready to be read. Then another created event is called for the same file.

The changed event is called, and the file is ready for access.

The changed event is called again for the same file.

.pgn files are chess game files. They can hold as many chess games as a file can be large.

As of now i'm not writing to a db because i know just enough to piss me off about them. So i'm writing them to another text file instead. My text file i created in my program will contain all games from all files. Which will eventually actually be a db which gathers statistics about these games.

I think file.Length will be enough to satisfy my users.

it is very rare a person would go into a pgn file and edit it. the only reason would be if they are playing the game blind (without a board) or if a certain website they play at has some bugs in the way they notate a chess game in the pgn file.

Both of these occurances are fairly rare, but they can happen so therefore as a programmer i feel obligated to do something to fix that.

 

so one day i may think of a solution but who knows

i'm curious of the CheckSum of a file. I know antivirus software uses this to determine if the file has been edited or something.

know anything about CheckSum?

i may start anoher post with that question

i'm not lazy i'm just resting before i get tired.
Posted

yes i've been over that idea before... basically it = the same two problems that i ahve alraedy..

hmmm well you know a new thought just occured (amazing considering i've been drinking)

If i am allowed to assume that the created and changed events are called twice everytime for a file then i could do that.

Well after mental analysis that creates a new problem. (assuming antivirus causes these events) I can not assume everyone has an antivirus that would fire these events twice.

So this is leading me in a new direction that might help though...

If all antivirus programs cause these events to fire like they do. I could check to see if antivirus software is enabled when the program starts. The more i think about this th emore problems it creates than solutions because more and more things could go wrong with this (let's say for some odd reason they disable the antivirus or something)

So this leads me to my newest idea to solve this.

If and only if all antivirus programs cause these events to fire again (and it only happens once no matter how many antivirus programs are running) Then i could try somehow to see if antivirus is enabled on that computer and THEN i could easily cancel out the extra event with a counter. This would force me to check for the change of status of antivirus software all the time with another thread which i'm not happy with but able to accept.

So where do i go with that idea? i almsot thin ki should start another post for that. but i'd like to see this one get over 100 reads.

It looks like we are breaking new ground thanks for your input once again. I hope this post of mine makes sense cuz i did have like 6 beers so i'm likely to have made some typos so bare with me.

thanks again

brandon

i'm not lazy i'm just resting before i get tired.
Posted

ArrayList that stores Filename and filesize

I'm not sure if CRC will work because I don't know where the file info (last created, last accessed, last written to, date created, etc) is stored. If somehow that info is also used in creating the CRC, you will probably get a unique CRC for each event raised on that file (assuming once the file is created the antivirus is going to access the file and do stuff). So I would try an array list that stores the filelength and the filesize.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...