FileInfo by month

T

tshad

Is there an easy way to get and move a set of FileInfo object (in a
FileInfo[] array) to another array by month?

I am getting list of files in my folder (about 100,000 of them):

FileInfo[] strFiles = null;

DirectoryInfo dirinfo = new DirectoryInfo(FilePath);

strFiles = dirinfo.GetFiles("*." + extension);

What I want to do is say get only the files with LastWriteTime equal to some
month?

I then pass the new array to my procedure which will process whatever is
there. I would them come back and do the same thing for another month and
then have that array processed.

GetFiles doesn't have a filter by month, so I have to do it after the fact.

I could loop through and look for files that match the request month and
then move that object to another array, but I was wondering if there is an
easier way.

Thanks,

Tom
 
P

Peter Duniho

Is there an easy way to get and move a set of FileInfo object (in a
FileInfo[] array) to another array by month?

I am getting list of files in my folder (about 100,000 of them):

FileInfo[] strFiles = null;

DirectoryInfo dirinfo = new DirectoryInfo(FilePath);

strFiles = dirinfo.GetFiles("*." + extension);

What I want to do is say get only the files with LastWriteTime equal to
some
month?

I then pass the new array to my procedure which will process whatever is
there. I would them come back and do the same thing for another month
and
then have that array processed.

GetFiles doesn't have a filter by month, so I have to do it after the
fact.

I could loop through and look for files that match the request month and
then move that object to another array, but I was wondering if there is
an
easier way.

I would use LINQ. For this specific example, you may find the "group"
clause (or Enumerable.GroupBy() method) useful; that will provide for you
an enumeration of enumerations, so that you're basically just doing the
filtering once (you could just use "where" instead, but then you'd have to
do that over and over for each month you wanted to check).

Pete
 
T

tshad

Peter Duniho said:
Is there an easy way to get and move a set of FileInfo object (in a
FileInfo[] array) to another array by month?

I am getting list of files in my folder (about 100,000 of them):

FileInfo[] strFiles = null;

DirectoryInfo dirinfo = new DirectoryInfo(FilePath);

strFiles = dirinfo.GetFiles("*." + extension);

What I want to do is say get only the files with LastWriteTime equal to
some
month?

I then pass the new array to my procedure which will process whatever is
there. I would them come back and do the same thing for another month
and
then have that array processed.

GetFiles doesn't have a filter by month, so I have to do it after the
fact.

I could loop through and look for files that match the request month and
then move that object to another array, but I was wondering if there is
an
easier way.

I would use LINQ. For this specific example, you may find the "group"
clause (or Enumerable.GroupBy() method) useful; that will provide for you
an enumeration of enumerations, so that you're basically just doing the
filtering once (you could just use "where" instead, but then you'd have to
do that over and over for each month you wanted to check).

Doing it over and over would be fine.

But I am working on VS 2005 so I would need to add it.

But how would you use it with FileInfo[]?

Thanks,

Tom
 
P

Peter Duniho

I would use LINQ. For this specific example, you may find the "group"
clause (or Enumerable.GroupBy() method) useful; that will provide for
you
an enumeration of enumerations, so that you're basically just doing the
filtering once (you could just use "where" instead, but then you'd have
to
do that over and over for each month you wanted to check).

Doing it over and over would be fine.

But I am working on VS 2005 so I would need to add it.

But how would you use it with FileInfo[]?

FileInfo[] implements IEnumerable<FileInfo>, which means all of the
Enumerable/LINQ methods that take an IEnumerable<T> would work. As I
mentioned, "group" and "where" can be used, with an appropriate predicate
delegate to do the comparison you desire for "where", or to select the
appropriate key for "group" (you'd probably want to group just on the
month, rather than the whole DateTime).

Of course, if you're stuck with VS2005, you won't be able to use the LINQ
syntax, but assuming you've installed the .NET 3.5 SDK, you can still use
the Enumerable class directly, using the GroupBy() or Where() methods
directly (the C# 3.0 LINQ syntax is just a convenience).

Pete
 
T

tshad

Peter Duniho said:
I would use LINQ. For this specific example, you may find the "group"
clause (or Enumerable.GroupBy() method) useful; that will provide for
you
an enumeration of enumerations, so that you're basically just doing the
filtering once (you could just use "where" instead, but then you'd have
to
do that over and over for each month you wanted to check).

Doing it over and over would be fine.

But I am working on VS 2005 so I would need to add it.

But how would you use it with FileInfo[]?

FileInfo[] implements IEnumerable<FileInfo>, which means all of the
Enumerable/LINQ methods that take an IEnumerable<T> would work. As I
mentioned, "group" and "where" can be used, with an appropriate predicate
delegate to do the comparison you desire for "where", or to select the
appropriate key for "group" (you'd probably want to group just on the
month, rather than the whole DateTime).

Of course, if you're stuck with VS2005, you won't be able to use the LINQ
syntax, but assuming you've installed the .NET 3.5 SDK, you can still use
the Enumerable class directly, using the GroupBy() or Where() methods
directly (the C# 3.0 LINQ syntax is just a convenience).
Sounds good. I'll try it.

Thanks,
 
T

tshad

tshad said:
Peter Duniho said:
I would use LINQ. For this specific example, you may find the "group"
clause (or Enumerable.GroupBy() method) useful; that will provide for
you
an enumeration of enumerations, so that you're basically just doing the
filtering once (you could just use "where" instead, but then you'd have
to
do that over and over for each month you wanted to check).

Doing it over and over would be fine.

But I am working on VS 2005 so I would need to add it.

But how would you use it with FileInfo[]?

FileInfo[] implements IEnumerable<FileInfo>, which means all of the
Enumerable/LINQ methods that take an IEnumerable<T> would work. As I
mentioned, "group" and "where" can be used, with an appropriate predicate
delegate to do the comparison you desire for "where", or to select the
appropriate key for "group" (you'd probably want to group just on the
month, rather than the whole DateTime).

Of course, if you're stuck with VS2005, you won't be able to use the LINQ
syntax, but assuming you've installed the .NET 3.5 SDK, you can still use
the Enumerable class directly, using the GroupBy() or Where() methods
directly (the C# 3.0 LINQ syntax is just a convenience).
Sounds good. I'll try it.

Well, I realize I am not going to be able to do that as the client doesn't
have it installed.

What would be the best way to compare dates to see if they are in the
request month (and year).

I want compare LastWriteTime from FileInfo and see if it is in "08/2009"
then "07/2009" then "06/2009".

I was looking at using DateTime somehow but not sure how to give it a date
and say just compare the months. If it is in August, process it.

But I also want to know when the DateTime is less than (or greater than) the
requested month/year to know when to stop searching. The FileInfo[] is
already sorted.

Thanks,

Tom
 
P

Peter Duniho

[...]
What would be the best way to compare dates to see if they are in the
request month (and year).

Compare them as DateTime values.
I want compare LastWriteTime from FileInfo and see if it is in "08/2009"
then "07/2009" then "06/2009".

I was looking at using DateTime somehow but not sure how to give it a
date
and say just compare the months. If it is in August, process it.

Have you actually looked at the documentation for the DateTime structure?
I'm sure if you read carefully, you'll be able to find a property that
tells you what month the DateTime value represents, as well as other
properties that may be helpful:
http://msdn.microsoft.com/en-us/library/system.datetime_properties.aspx
But I also want to know when the DateTime is less than (or greater than)
the
requested month/year to know when to stop searching. The FileInfo[] is
already sorted.

If you have a DateTime value with the start and/or end point for your
search, you can simply compare that to the DateTime value retrieved from
the FileInfo object.

Pete
 
T

tshad

Peter Duniho said:
[...]
What would be the best way to compare dates to see if they are in the
request month (and year).

Compare them as DateTime values.
I want compare LastWriteTime from FileInfo and see if it is in "08/2009"
then "07/2009" then "06/2009".

I was looking at using DateTime somehow but not sure how to give it a
date
and say just compare the months. If it is in August, process it.

Have you actually looked at the documentation for the DateTime structure?
I'm sure if you read carefully, you'll be able to find a property that
tells you what month the DateTime value represents, as well as other
properties that may be helpful:
http://msdn.microsoft.com/en-us/library/system.datetime_properties.aspx
But I also want to know when the DateTime is less than (or greater than)
the
requested month/year to know when to stop searching. The FileInfo[] is
already sorted.

If you have a DateTime value with the start and/or end point for your
search, you can simply compare that to the DateTime value retrieved from
the FileInfo object.
The problem I have the month and year I want to compare and then I have the
LastWriteTime and get whether the date is past (or in my case before since I
have the array sorted in reverse starting from today).

I found an algorithm that seems to work.

ktr = 12 * (monthToProcess.Year -
DateTime.Parse(fl.LastWriteTime.ToString()).Year) +
(monthToProcess.Month -
DateTime.Parse(fl.LastWriteTime.ToString()).Month);

If ktr is < 0 than I haven't got to the month I need so go get the next one.
If ktr is = 0 I can process this one as it is the month I requested.
If ktr is> 0 (number of months from the month requested) I am done and can
go get the next month (which would be monthToProcess.AddMonths(-1)).

Thanks,

Tom
 
P

Peter Duniho

The problem I have the month and year I want to compare and then I have
the
LastWriteTime and get whether the date is past (or in my case before
since I
have the array sorted in reverse starting from today).

I found an algorithm that seems to work.

ktr = 12 * (monthToProcess.Year -
DateTime.Parse(fl.LastWriteTime.ToString()).Year) +
(monthToProcess.Month -
DateTime.Parse(fl.LastWriteTime.ToString()).Month);

There's no reason to convert the FileInfo DateTime properties to strings,
especially if you're just going to turn around and parse the result back
to a DateTime value. Please tell me you can see how silly that is. :)
If ktr is < 0 than I haven't got to the month I need so go get the next
one.
If ktr is = 0 I can process this one as it is the month I requested.
If ktr is> 0 (number of months from the month requested) I am done and
can
go get the next month (which would be monthToProcess.AddMonths(-1)).

Instead of something complicated like that, how about (in pseudo/C# code):

DateTime dtProcess = ...;
FileInfo[] rgfi = ...;
int ifi = 0;

while (ifi < rgfi.Length && (rgfi[ifi].Year != dtProcess.Year ||
rgfi[ifi].Month != dtProcess.Month))
{
ifi++;
}

while (ifi < rgfi.Length && rgfi[ifi].Year == dtProcess.Year &&
rgfi[ifi].Month == dtProcess.Month)
{
FileInfo fiCur = rgfi[ifi++];

// process the FileInfo object
}

In other words, just scan the array until you find the first record that
has the year and month you want, and then process all the elements until
you get to one that's not the year and month you want.

It's not very efficient; if the month and year aren't actually
represented, then you'd wind up scanning the entire list. But then, you
already said you don't need it to be efficient. And after all, if you
were going to worry about efficiency, you'd group the data by year/month
anyway.

Hope that helps.

Pete
 
T

tshad

Peter Duniho said:
The problem I have the month and year I want to compare and then I have
the
LastWriteTime and get whether the date is past (or in my case before
since I
have the array sorted in reverse starting from today).

I found an algorithm that seems to work.

ktr = 12 * (monthToProcess.Year -
DateTime.Parse(fl.LastWriteTime.ToString()).Year) +
(monthToProcess.Month -
DateTime.Parse(fl.LastWriteTime.ToString()).Month);

There's no reason to convert the FileInfo DateTime properties to strings,
especially if you're just going to turn around and parse the result back
to a DateTime value. Please tell me you can see how silly that is. :)
If ktr is < 0 than I haven't got to the month I need so go get the next
one.
If ktr is = 0 I can process this one as it is the month I requested.
If ktr is> 0 (number of months from the month requested) I am done and
can
go get the next month (which would be monthToProcess.AddMonths(-1)).

Instead of something complicated like that, how about (in pseudo/C# code):

DateTime dtProcess = ...;
FileInfo[] rgfi = ...;
int ifi = 0;

while (ifi < rgfi.Length && (rgfi[ifi].Year != dtProcess.Year ||
rgfi[ifi].Month != dtProcess.Month))
{
ifi++;
}

while (ifi < rgfi.Length && rgfi[ifi].Year == dtProcess.Year &&
rgfi[ifi].Month == dtProcess.Month)
{
FileInfo fiCur = rgfi[ifi++];

// process the FileInfo object
}

In other words, just scan the array until you find the first record that
has the year and month you want, and then process all the elements until
you get to one that's not the year and month you want.

It's not very efficient; if the month and year aren't actually
represented, then you'd wind up scanning the entire list. But then, you
already said you don't need it to be efficient. And after all, if you
were going to worry about efficiency, you'd group the data by year/month
anyway.
True.

Thanks,

Tom
Hope that helps.

Pete
Thanks,

Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top