0

Now I have a directory with bunch files with format of name like "EXT2-401-B-140422-1540-1542.mp4", within which the "140422" part indicates the date. Now assume that this bunch of files have the dates like 140421, 140422, 140423...(for every date there are couple of files). Now I shall sort these files according to their dates, so I'd like to know how could I get these names (140421,140422,etc). I tried like this:

directory = new DirectoryInfo(camera_dir);    
string[] date = new string[directory.GetFiles().Length];
foreach (FileInfo file in directory.GetFiles())
{ 
    foreach(string name in date)
    {
        name = file.Name.Substring(11, 6);
    }
}

And the error message is that I can't assign to name. So anybody could help?

3

5 Answers 5

5

You can use LINQ to simplify this a bit.

To get filenames only, you simply need to project each FileInfo into a string:

var dates = directory
    .EnumerateFiles("*.mp4")
    .Select(f => f.Name)
    .ToArray();

To get an ordered list, you also need to use OrderBy and specify the value to be used for ordering:

var dates = directory
    .EnumerateFiles("*.mp4")
    .Select(f => f.Name)
    .OrderBy(f => f.Substring(11, 6)) // this will throw if string is too short
    .ToArray();

You should also probably add some validation to prevent exceptions when filenames are not formatted properly. The least you can do is check if the string is long enough to have these 6 characters extracted:

var dates = directory
    .EnumerateFiles("*.mp4")
    .Select(f => f.Name)
    .Where(f => f.Length >= 17) // check if there are enough characters
    .OrderBy(f => f.Substring(11, 6))
    .ToArray();
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you for the cool method. I guess that makes sense(since I've no background of LINQ). I shall study more! :)
@jcraffael: I've updated the answer a bit to do some basic validation.
@Michael: yeah, that's the lazy IEnumerable version more suitable for LINQ queries.
That's the cleanest way to do it so far.
@Michael: yeah, I also decided to remove that part from the answer to simplify it.
|
1

try this:

    var files = directory.GetFiles();
    string[] dates = new string[files.Length];
    for(int i = 0; i < files.Length; i++)
    { 
        dates[i] = files[i].Name.Substring(11, 6);
    }

1 Comment

Thank you! That's exactly what I expect :)
0
directory = new DirectoryInfo(camera_dir);    
string[] date = new string[directory.GetFiles().Length];
int i=0;
foreach (FileInfo file in directory.GetFiles())
{ 
    name[i] = file.Name.Substring(11, 6);
    i++;
}

2 Comments

Without setting the upper limit of i? That seems cool. Thank you for the new method for me :)
why increment i in foreach loop when you can use for loop?
0

In fact you are asking two questions.

  1. You cannot assign a variable from the foreach. Create a new one to store the name in.

  2. For the second part, how to extract it: use this regex:

    string s = Regex.Replace(file.Name, @"(.*?)\-(.*?)\-(.*?)\-(.*?)\-(.*)", "$4");
    

    The ? makes the regex non-greedy, meaning that this expression will find the text after the third dash.

4 Comments

I don't think the OP is asking about regex, if he's certain of the file name format then I'd definitely consider the substring approach as it is more than likely more efficient
OP said "so I'd like to know how could I get these names". So I think he does.
Thanks for the reply. The regex is cool but the substring approach i think is more suitable.
@jcraffael: No problem. I can keep it here for future reference if you want.
0

I would be doing something like creating a class for the file name (if they are all the same structure) then splitting them out (apologies for reworking the entire code, also what the other guys are saying is something worth noting about foreach's not begin able to modify the set)...

public class MyFile 
{
    // EXT2-401-B-140422-1540-1542.mp4
    public string part1 { get; set;}
    public string part2 { get; set;}
    public string part3 { get; set;}
    public string date { get; set;}
    public string part5 { get; set;}
    public string part6 { get; set;}

    void MyFile(string fileName)
    {
        string[] parts = fileName.split('-');

        part1 = parts[0];
        part2 = parts[1];
        part3 = parts[2];
        date  = parts[3];
        part5 = parts[4];
        part6 = parts[5];
    }
}

then you can loop through...

directory = new DirectoryInfo(camera_dir);    

List<MyFile> myFiles = new List<MyFile>();

foreach (FileInfo file in directory.GetFiles())
{    
   myFiles.Add(new MyFile(file.Name));
}

Then you can sort, select, "blah" on any of the files using linq...

EDIT:

Additionally, if your previous code worked, you would end up with the date array being full of one date because you are trying to set the name (being each element in the array) to the current file name for the length of the array every single iteration of the directory.GetFiles() array.

Name the 'parts' something useful to you.

3 Comments

In this specific example, it's overkill and leads to unneeded use of memory and stuff I'm not competent enough to explain in a short comment. But I guess he will find use for the other parts someday, so it's still worth something :p
I fully get what you are saying, and you are right. I just provided this because I can see that the two 'fields' after the date are the timespan of the recording. If OP want them as well they would be much better off with a class instead of two arrays that stored date and time. Scope of the project is hard to determine from the question (and I may have broken protocol here :P) but I just wanted to be concise.
Yes exactly it happens that the date arrary is full of the same date. Fortunately I could handle that. I'm pretty sure your solution solves that problem perfectly but it's a bit hard...anyway thank you very much for the solution, probably this idea solves other tougher problem :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.