Autor Beitrag
Think21
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Mo 07.01.13 21:44 
Hallo Liebe Gemeinde,

kurz vorweg - ich bin noch relativ neu in der C# Programmierung und beschäftige mich gerade mit Dateioperationen ( StreamWriter, StreamReader).
Zu meinem Problem:
Ich möchte aus einer Textdatei z.B.
--------------------txt-Datei------------------
Franz 21 Jahre
Herbert 50 Jahre
Alois 49 Jahre
--------------------txt-Datei-Ende-------------

immer nur das Alter einlesen über einen Stream, dann in einem Array zwischen speichern und danach das Alter in einer anderen Datei an einer bestimmten Stelle wieder schreiben.
Ich habe über Google die Methoden Seek, Peek gefunden, aber die erscheinen mir etwas umständlich... Jetzt wollte ich mal fragen wie ihr so ein Problem mit C# lösen würdet.

Grüße
Karsten


Moderiert von user profile iconChristian S.: Topic aus C# - Die Sprache verschoben am Mo 07.01.2013 um 21:03
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Mo 07.01.13 22:29 
Ich würde die Datei zeilenweise laden und auf jede Zeile einen regex loslassen. Der zerlegt mir dann die ganze Zeile in die einzelnen Info-Happen.
Um es ganz schick zu haben kannst du eine Klasse schreiben und für die Datei dann eine generische Liste machen, pro Zeile ein Objekt :)

Ich guck gerade mal ob ich da was zusammen flicken kann...
... erfolgreich! Hier mein Code-Beispiel:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;

namespace Test_1
{
    public partial class Form1 : Form
    {
        string[] content = new string[] {"Franz 21 Jahre""Herbert 50 Jahre""Alois 49 Jahre"};

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var sr = new StreamReader(@"c:\abc.txt");

            var Persons = new List<Person>();
            while (!sr.EndOfStream)
            {
                Persons.Add(new Person(sr.ReadLine()));
            }
            sr.Close();
        }
    }

    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }

        private static Regex ParseExpression = new Regex(@"(.+) (\d+) Jahre", RegexOptions.Compiled);

        public Person(string rawdata)
        {
            var result = ParseExpression.Match(rawdata);
            Name = result.Groups[1].Value;
            Age = int.Parse(result.Groups[2].Value);
        }
    }
}

Edit: das Beispiel um tatsächliche Dateioperationen ergänzt.
Noch praktischer wären natürlich xml Dateien zum deserialisieren 8)

Für diesen Beitrag haben gedankt: Think21
Think21 Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Mo 07.01.13 23:27 
hi jfheins,

danke für die schnelle Hilfestellung.
Ich habe mir dein Programm mal durchgesehen.
Mal sehen ob ich das auch richtig verstanden habe...

- Du liest von der Datei abc.txt solange ein bis sr.Readline = NULL ergibt...
- Für jedes eingelesene Objekt wird eine neue Person erzeugt.
- In der Klasse Person gibt es die Attribute Name und Alter

-> Jetzt hab ich schon ein Problem das mit dem Regex verstehe ich noch nicht ganz...

Den Sinn verstehe ich allerdings nicht die Syntax..

Mein Problem ist eigentlich dass ich meinen Stream so steuern möchte, damit er mir nur das Alter einliest am Besten in ein Array und danach möchte ich es an einer bestimmten Stelle in einer anderen Datei wieder schreiben.

anderes Beispiel:

----------------txt-Datei-----------------
Das hier ist eine Temperatur Logfile...
Temp_01=21,4°C
Temp_02=44,09°C
.
.
.
---------------txt-Datei-Ende-------------

und jetzt möchte ich nur die Temperaturen mit einem StreamReader() einlesen und in einem double TemperaturArray speichern und später in einer neuen
Txt-Datei wieder an einer bestimmten Stelle einfügen.
Kann ich mir nicht irgendwie einen Stream schreiben dass er nach Temp_XX sucht, und nach dem '=' mir den double Wert in ein Double Array schreibt?

Oder bin ich ganz auf dem Holzweg?

Grüße und vielen Dank schonmal :)
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Di 08.01.13 00:04 
Klar kannst du auch schon beim lesen bestimmte Infos ignorieren.
Nur würde ich eine Liste dem Array vorziehen. In dem konkreten fall sieht's dann so aus:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
namespace Test_1
{
    public partial class Form1 : Form
    {
        private static Regex ParseExpression = new Regex(@"Temp_(\d+)=(\d+(,\d+)?)°C", RegexOptions.Compiled);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var Values = new List<double>();

            using (var sr = new StreamReader(@"c:\abc.txt"))
            {              
                while (!sr.EndOfStream)
                {
                    var line = sr.ReadLine();
                    var match = ParseExpression.Match(line);
                    Values.Add(double.Parse(match.Groups[2].Value));
                }  
            }
        }
    }
}

Wegen dem ° zeichen aufpassen dass das richtig codiert ist. Sonst beim Streamreader die passende Kodierung angeben. Und natürlich aufpassen dass die Spracheinstellungen zum Dezimalseperator passen.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 08.01.13 00:06 
Zitat:
Oder bin ich ganz auf dem Holzweg?


Gefühlt ja ;)

Zitat:
und jetzt möchte ich nur die Temperaturen mit einem StreamReader() einlesen


Wie stellst du fest das das was du einliest die Temperatur ist? In dem du alles einliest und das wegwirfst was nicht Temperatur ist. Du kannst nicht nur das einlesen was dich interessiert dafür bräuchte der Streamreader hellseherische Fähigkeiten. Egal was du tust und wie du es machst. Es wird einmal die gesamte Datei durch den Speicher gehen. Es macht also keinen großen Sinn am StreamReader rum zu optimieren.
Think21 Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Di 08.01.13 09:27 
@Nussknacker vielen Dank für deine kompetente Hilfestellung,
ich werde mich jetzt ersteinmal mit der Klasse Regex ausseinandersetzen aber du hast damit den Nagel auf den Kopf getroffen. Vielen Dank nochmal :)

@Ralf Jansen "Wie stellst du fest das das was du einliest die Temperatur ist?"
Genau das war eigentlich mehr oder weniger meine Frage ;) vielleicht hab ich mich nicht gut genug ausdrücken können. Die Gesamte Datei darf ruhig eingelesen werden, allerdings wusste ich dann nicht wie ich aus der Datei bestimmte "Teilausschnitte" extrahieren kann.

Trotzdem vorerst mal vielen Dank

Grüße