C# .net - Read file into array 6 lines at a time.

Hi,

I have a text file with records made up of 6 lines.

I need to read each record of 6 lines into an array. Sort alphabetically on the first record then recreate the file so its in alphabetical order.

Example file:
Lastname Firstname
Two
Three
Four
Five
Six
Smith John
USA
Kentucky
Male
Married
Blue

Open in new window

In the example, there are two records made up of 6 lines each.

Can anyone assist with this logic? I can find examples when the file is in CSV format but this file structure is weird.

Thanks
mhdiAsked:
Who is Participating?
 
käµfm³d 👽Connect With a Mentor Commented:
If you install MoreLinq form the NuGet package manager, then you could use the following:

using (StreamWriter writer = new StreamWriter("output.txt"))
{
    File.ReadLines("file.txt")
        .Batch(6)
        .OrderBy(batch => batch.First())
        .ForEach(batch => batch.ForEach(line => writer.WriteLine(line)));
}

Open in new window


Note that this approach is highly dependent on your file structure being exact. If any group of 6 lines is really a group of 5 or less (or more) lines, excluding lines that are blank, then this approach would fail.
0
 
gt2847cSr. Security ConsultantCommented:
Just a clarification question...  Is this a school/homework related project?
0
 
mhdiAuthor Commented:
no :) its a work related question.

I have a text file of employees with over 2,500 records that I need to sort easily when required.
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

 
gt2847cConnect With a Mentor Sr. Security ConsultantCommented:
If you're looking to do this in C# (an assumption based on the tags)...  I'm not sure I'd use an array for this, as you don't really get a lot of benefit doing it that way, rather, I'd do this:

1.

Create an object representing your record.

2.

Implement  IComparable interface (CompareTo function) which allows you to use the .Sort() function on collections.  CompareTo allows you to define how you want to sort your objects (which fields in what order, etc).  

3.

Create a static method (call it ReadARecord for purposes of this discussion) that takes a Stream or equivalent file source, news up a record object, reads 6 lines from the source and places them in appropriate fields/properties then returns the populated record object.

4.

Create a static method that reads a file (ReadInAFile) and returns an object collection (Enumerable, List, Dictionary, what have you).  
The ReadInAFile method would call the ReadARecord method to handle individual records.

Obviously you could take this and create a bunch of things out of it, but I'm not sure what the end goal is for this.  If you're just looking to fiddle with the file upon occasion, there's a number of other less complicated ways to do this (simple program that reads six lines, turns them into a .CSV file and dump the CSV into Excel or the like).

Let me know what your goal is and I can give you some more directed advice...
0
 
mhdiAuthor Commented:
Thanks guys, I am learning fast here. I hadnt see NuGet before which is really cool.

I have the application working in .net4.

It would be great if I can get it working in .net 3.5 which I beleive is standard in windows 7?

The only issue is this "File.ReadLines(path)" as ReadLines is not available in net3.5. Is there anything I can change it too?

if (file.ShowDialog() == DialogResult.OK)
            {
                btnInput.Enabled = false;
                btnSort.Enabled = false;
                
                newPath = file.FileName;
                lblOutput.Text = newPath;

                using (StreamWriter writer = new StreamWriter(newPath))
                {
                    File.ReadLines(path)
                        .Batch(6)
                        .OrderBy(batch => batch.First())
                        .ForEach(batch => batch.ForEach(line => writer.WriteLine(line)));
                }

Open in new window

0
 
mhdiAuthor Commented:
I've changed "File.ReadLines(path)" to "File.ReadAllLines(path)" which seems to work.
0
 
gt2847cSr. Security ConsultantCommented:
I get to learn something new too, I hadn't seen the MoreLinq (which appears quite cool - thanks kaufmed)..  

On your substitution above:

File.ReadLines(path) returns an IEnumerable<string>,
File.ReadAllLines(path) returns a string[] (which is also behind the scenes an IEnumerable)
so Linq extensions should work just fine.

ReadLines was introduced in 4 and is available through 4.5
ReadAllLines was introduced in 2 and is available through 4.5

Other than the return type, I've never tested them against each other for performance or memory usage, but with the small number of records you mentioned above, it's rather academic.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.