1

I have a text file with contents like so:

01 Dir1
abcd
efg
hij
klm
nop
qrs
tuv
wxy
zab
yxw
vut
dcb

02 Dir2
abcd
efg
hij
klm
nop
qrs
tuv
wxy
zab
yxw
vut
dcb

I get an array which is created by reading the file:

string[] lines = File.ReadAllLines(path);

This gives me an array will all the entries including the empty one.

The idea behind the text file is that there is a folder and the files in that folder following it. So, "01 Dir1" is a folder and every line after that till an empty line is a file.

What I am trying is to have a list of arrays, so from the above sample there will be two arrays in the list, one starting from "01 Dir1" till the empty entry and the next from "02 Dir2" till the end.

I can loop through the initial array and create list for each individual directory but is there another way to do it?

The problem with that approach is that it will end up having the same data in different sets in memory, one from the ReadAllLines array and other the subs from it.

7
  • 1
    Can you not just split on the space? Commented Jul 16, 2014 at 9:00
  • The problem with that approach is that it will end up having the same data in different sets in memory, one from the ReadAllLines array and other the subs from it.... why is this a problem? The garbage collector will take take of the objects you don't need anymore when the object goes out of scope. Commented Jul 16, 2014 at 9:06
  • 1
    But if you don't want the results of ReadAllLines in a single array then don't use it. There are other ways to read text files that you can customize how the file is read. Commented Jul 16, 2014 at 9:08
  • @psubsee2003 can't rely on GC here. What if the entries are more. Your second comment is not helpful. Commented Jul 16, 2014 at 9:10
  • @psubsee2003 The problem is not just an object being GCed. Arrays need contiguous memory blocks and can easily lead to out of memory exceptions. Commented Jul 16, 2014 at 9:11

4 Answers 4

1

do you wan´t something like the following?

This will read line after line and you can decide what to do with it. So you won´t get a big string array containing all entries. The result here will be a list containing string arrays and skipping the blank lines.

//This will be the resulting list of arrays
var fileArrayList = new List<string[]>();
var filereader = new System.IO.StreamReader("yourfile");
var tmpArr = new List<string>();
var line = "";
while((line = filereader.ReadLine()) != null)
{
   if(String.IsNullOrEmpty(line){
       //put this array to our list
       fileArrayList.Add(tmpArr.ToArray());
       //clean the temp one
       tmpArr.Clear();
   }else
   {
       tmpArr.Add(line);
   }
}
//add the last entry
fileArrayList.Add(tmpArr.ToArray());
tmpArr = null;
//close the stream
filereader.Close();
Sign up to request clarification or add additional context in comments.

Comments

0

This way you can have a Dictionary which contains directory names as keys and List<string>s of file names as values.

I didn't handle the exceptional situations

Dictionary<string, List<string>> data = new Dictionary<string,List<string>>();
using (StreamReader reader = File.OpenText(filename))
{
    while (!reader.EndOfStream)
    {
        string dirName = reader.ReadLine();
        List<string> currentFiles = new List<string>();
        data.Add(dirName, currentFiles);
        string fileName;
        while (!reader.EndOfStream && (fileName = reader.ReadLine()).Trim() != "")
        {
            currentFiles.Add(fileName);
        }
    }
}

1 Comment

This will help in using the Dictionary further. Thanks appreciate your time.
0
list<string> listBeforeEmpty = new list<string>();
list<string> listAfterEmpty = new list<string>();

//Indicates whether the loop is before the empty line or not
bool isEmptyLineFound = false;

 for (int i = 0; i < lines.Length; i++)
    {

     //If the empty line was found
     if (lines[i].CompareTo(@"") == 0)
            {
                isEmptyLineFound = true;
            }

    //Add the line to the right list
     if (isEmptyLineFound == false) 
          listBeforeEmpty .Add(lines[i]);
     else listAfterEmpty .Add(lines[i]);

    }

Comments

0

I decided to have a go at this for fun. This is what I came up with, it should work:

    private static string[] _arr = new string[] // The stuff you read from file.

    private static List<string[]> _arrays = new List<string[]>(); 

        while (_arr.Length > 0)
        {
            var a = _arr.TakeWhile(s =>
            {
                var li = _arr.ToList();
                return 
                    s != string.Empty // Take it if the string isn't empty.
                    || (s == string.Empty && li.IndexOf(s) == 0) // Or if it's empty, but it's the first element in the array (it's the next one after we've just finished a batch)
                    || li.IndexOf(s) == _arr.Length; // And take it if it's the last element (in the case of an empty string as the last element)
            }).ToArray();

            _arrays.Add(a);

            // Re-create the array to only include the stuff we haven't solved yet.
            var l = _arr.ToList();
            l.RemoveRange(0, a.Length);
            _arr = l.ToArray();
        }

It's a bit hackish and could be improved, but it should be something you can work with.

On a side note, you should probably use an alternate way of reading your file and determining these individual arrays while reading the file. It's more efficient, and probably easier too.

2 Comments

Don't answer if you don't want to. Shrouding half baked thoughts as answers doesn't help either.
@Codehelp You're right, I redacted that part. I did want to answer, because it's an interesting question.

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.