Чтение строки от streamreader без потребления?

Это работает для вас? Фигуры могут быть изменены позже

      library(DiagrammeR)
grViz(
  "digraph{
    graph[layout='dot',outputorder=edgesfirst,overlap=T,rankdir=LR]

 b[label='population=BARI_POP4_5_PRIMARY_CN.csv']
 c [label='12']
 d[label='ACR50']
 b->c[label='link1']
 c->d[label='link2']
 }")

В настоящее время: enter image description here

Изменения формы: появляется приятнее

grViz(
  "digraph{
    graph[layout='dot',outputorder=edgesfirst,overlap=T,rankdir=LR]
    node[shape='box']

 b[label='population=BARI_POP4_5_PRIMARY_CN.csv']
 c [label='12']
 d[label='ACR50']
 b->c[label='link1']
 c->d[label='link2']
 }")

[113 ] enter image description here

25
задан Casebash 21 March 2010 в 10:42
поделиться

4 ответа

Проблема в том, что базовый поток может быть недоступен для поиска. Если вы посмотрите на реализацию средства чтения потока, в нем используется буфер, поэтому он может реализовать TextReader.Peek (), даже если поток недоступен для поиска.

Вы можете написать простой адаптер, который считывает следующую строку и буферизует ее внутри, примерно так:

 public class PeekableStreamReaderAdapter
    {
        private StreamReader Underlying;
        private Queue<string> BufferedLines;

        public PeekableStreamReaderAdapter(StreamReader underlying)
        {
            Underlying = underlying;
            BufferedLines = new Queue<string>();
        }

        public string PeekLine()
        {
            string line = Underlying.ReadLine();
            if (line == null)
                return null;
            BufferedLines.Enqueue(line);
            return line;
        }


        public string ReadLine()
        {
            if (BufferedLines.Count > 0)
                return BufferedLines.Dequeue();
            return Underlying.ReadLine();
        }
    }
29
ответ дан 28 November 2019 в 21:32
поделиться

Вы можете сохранить позицию, обращающуюся к StreamReader.BaseStream.Position, затем прочитать строку на следующей строке, выполнить тест, а затем выполнить поиск позиции, прежде чем читать строку:

            // Peek at the next line
            long peekPos = reader.BaseStream.Position;
            string line = reader.ReadLine();

            if (line.StartsWith("<tag start>"))
            {
                // This is a new tag, so we reset the position
                reader.BaseStream.Seek(pos);    

            }
            else
            {
                // This is part of the same node.
            }

Это много искать и перечитывать одни и те же строки. Используя некоторую логику, вы можете вообще избежать этого - например, когда вы видите начало нового тега, закрываете существующую структуру и запускаете новую - вот основной алгоритм:

        SomeStructure myStructure = null;
        while (!reader.EndOfStream)
        {
            string currentLine = reader.ReadLine();
            if (currentLine.StartsWith("<tag start>"))
            {
                // Close out existing structure.
                if (myStructure != null)
                {
                    // Close out the existing structure.
                }

                // Create a new structure and add this line.
                myStructure = new Structure();                   
                // Append to myStructure.
            }
            else
            {
                // Add to the existing structure.
                if (myStructure != null)
                {
                    // Append to existing myStructure
                }
                else
                {
                    // This means the first line was not part of a structure.
                    // Either handle this case, or throw an exception.
                }
            }
        }
4
ответ дан seddy 28 November 2019 в 21:32
поделиться

В чем проблема? В любом случае верните следующую строку. Проверьте, новый ли это узел, если нет, добавьте его в структуру. Если это так, создайте новую структуру.

// Not exactly C# but close enough
Collection structs = new Collection();
Struct struct;
while ((line = readline()) != null)) {
    if (IsNode(line)) {
        if (struct != null) structs.add(struct);
        struct = new Struct();
        continue;
    }
    // Whatever processing you need to do
    struct.addLine(line);
}
structs.add(struct); // Add the last one to the collection

// Use your structures here
foreach s in structs {

}
1
ответ дан 28 November 2019 в 21:32
поделиться

Вот что я зашел так далеко. Я пошел больше по разделенному маршруту, чем по стриминговому маршруту, построчно.

Я уверен, что есть несколько мест, которые умирают, чтобы быть более элегантными, но на данный момент это, кажется, работает.

Пожалуйста, позвольте мне знайте, что вы думаете

struct INDI
    {
        public string ID;
        public string Name;
        public string Sex;
        public string BirthDay;
        public bool Dead;


    }
    struct FAM
    {
        public string FamID;
        public string type;
        public string IndiID;
    }
    List<INDI> Individuals = new List<INDI>();
    List<FAM> Family = new List<FAM>();
    private void button1_Click(object sender, EventArgs e)
    {
        string path = @"C:\mostrecent.ged";
        ParseGedcom(path);
    }

    private void ParseGedcom(string path)
    {
        //Open path to GED file
        StreamReader SR = new StreamReader(path);

        //Read entire block and then plit on 0 @ for individuals and familys (no other info is needed for this instance)
        string[] Holder = SR.ReadToEnd().Replace("0 @", "\u0646").Split('\u0646');

        //For each new cell in the holder array look for Individuals and familys
        foreach (string Node in Holder)
        {

            //Sub Split the string on the returns to get a true block of info
            string[] SubNode = Node.Replace("\r\n", "\r").Split('\r');
            //If a individual is found
            if (SubNode[0].Contains("INDI"))
            {
                //Create new Structure
                INDI I = new INDI();
                //Add the ID number and remove extra formating
                I.ID = SubNode[0].Replace("@", "").Replace(" INDI", "").Trim();
                //Find the name remove extra formating for last name
                I.Name = SubNode[FindIndexinArray(SubNode, "NAME")].Replace("1 NAME", "").Replace("/", "").Trim(); 
                //Find Sex and remove extra formating
                I.Sex = SubNode[FindIndexinArray(SubNode, "SEX")].Replace("1 SEX ", "").Trim();

                //Deterine if there is a brithday -1 means no
                if (FindIndexinArray(SubNode, "1 BIRT ") != -1)
                {
                    // add birthday to Struct 
                    I.BirthDay = SubNode[FindIndexinArray(SubNode, "1 BIRT ") + 1].Replace("2 DATE ", "").Trim();
                }

                // deterimin if there is a death tag will return -1 if not found
                if (FindIndexinArray(SubNode, "1 DEAT ") != -1)
                {
                    //convert Y or N to true or false ( defaults to False so no need to change unless Y is found.
                    if (SubNode[FindIndexinArray(SubNode, "1 DEAT ")].Replace("1 DEAT ", "").Trim() == "Y")
                    {
                        //set death
                        I.Dead = true;
                    }
                }
                //add the Struct to the list for later use
                Individuals.Add(I);
            }

            // Start Family section
            else if (SubNode[0].Contains("FAM"))
            {
                //grab Fam id from node early on to keep from doing it over and over
                string FamID = SubNode[0].Replace("@ FAM", "");

                // Multiple children can exist for each family so this section had to be a bit more dynaimic

                // Look at each line of node
                foreach (string Line in SubNode)
                {
                    // If node is HUSB
                    if (Line.Contains("1 HUSB "))
                    {

                        FAM F = new FAM();
                        F.FamID = FamID;
                        F.type = "PAR";
                        F.IndiID = Line.Replace("1 HUSB ", "").Replace("@","").Trim();
                        Family.Add(F);
                    }
                        //If node for Wife
                    else if (Line.Contains("1 WIFE "))
                    {
                        FAM F = new FAM();
                        F.FamID = FamID;
                        F.type = "PAR";
                        F.IndiID = Line.Replace("1 WIFE ", "").Replace("@", "").Trim();
                        Family.Add(F);
                    }
                        //if node for multi children
                    else if (Line.Contains("1 CHIL "))
                    {
                        FAM F = new FAM();
                         F.FamID = FamID;
                        F.type = "CHIL";
                        F.IndiID = Line.Replace("1 CHIL ", "").Replace("@", "");
                        Family.Add(F);
                    }
                }
            }
        }
    }

    private int FindIndexinArray(string[] Arr, string search)
    {
        int Val = -1;
        for (int i = 0; i < Arr.Length; i++)
        {
            if (Arr[i].Contains(search))
            {
                Val = i;
            }
        }
        return Val;
    }
0
ответ дан 28 November 2019 в 21:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: