C# einlesen von datei

Parrain

Cadet 3rd Year
Registriert
Sep. 2012
Beiträge
51
hallo zusammen,

habe einen kleinen problem der vielleicht für andere einfach ist ;)

ich versuche einen text datei in einer tabelle einzulesen. und weiss gerade nicht wo mein fehler ist, oder was mir noch fehlt..

ich habe schon im Hauptprogramm eine Tabelle erstellt:

DataTable dtWorkTable = new DataTable(); ....

jetzt möchte ich aus einer Text datei daten auslesen und in der Tabelle (dtWorkTable) einlesen, und zwar mit dem Stream Reader..ich habe dann einen neuen Projekt geöffnet den ich Import genannt habe, und das so angefangen. Datei sieht so aus:

==166-70-SA21 §=000EEA011 §+H011 §-EA1 §1 §Rittal §SZ4140.830 §SZ4140.830 §Systemleuchte LED

mien Code sieht bis jetzt so aus:

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;
using System.Windows.Forms;


namespace HWG2
{
    class Import
    {

        public DataTable ImportDaimlerBR205(DataTable dtWorkTable, string path)
        {

            try
            {
                if (File.Exists(path))               // Überprüfen ob Datei existiert
                {                   
                }

                List<string> list = new List<string>();                   // Liste erstellen
                using (StreamReader sr = new StreamReader(path))
                {
                    
                    String[] readText = File.ReadAllLines(path);          //  lesen; öffnet die Datei, liest alle Zeilen und fügt die einzelnen in einen Stringarray
                    while (!sr.EndOfStream)                               // Schleife
                    {                                                                    
                   
                    }
                }
            }

            catch (Exception e) 
            {
                MessageBox.Show(e.Message, "Fehler");
            }                        
          
            return dtWorkTable;
        }
    }
}


über einen bsp. Code werde ich sehr dankbar sein. und Danke im voraus

MFG
 
Hi,

und was macht dein Code bzw. was macht er nicht? Was geht, was geht nicht?

Wenn dir die Tutorials, die man zu dem Thema haufenweise im Netz findet nicht reichen dann wird's eng.

VG,
Mad
 
Hi Mad,

es ist so das ich von meinem Form1.cs auf den Import.cs zugreifen soll..habe ich denke ich richtig gemacht:

Code:
// Zugriff auf der DataTable

            xd.Load("" + (string)config.GetValue("TreeStartAdresse", typeof(string)) + "" + treeView1.SelectedNode.FullPath.Replace(treeView1.TopNode.Text, string.Empty) + "\\" + treeView1.SelectedNode.Text + ".xml");
            
            Import Text = new Import();             //Objekt vom typ Import definieren, um zugriff auf Import.cs zu ermöglichen 

            dtWorkTable = Text.ImportDaimlerBR205(dtWorkTable, xd.SelectSingleNode("Configuration/FileDirectory/txbGeräteliste").InnerText.ToString());

            ////                               (Tabelle      //   ,  // Pfad zu Gerätelistentext)

aber es tut sich leider nicht!!!??? fehlt mit sicherheit etwas, oder ich übersehe etwas..übrigens bin ein frichling in C# :(

und danke für deine antwort :)
 
Hi,

ok, dein "Import.cs" dürfte eine Klasse sein, ich kenne leider deine Projektstruktur nicht. Warum genau muss es ein StreamReader sein?

Ich würde dir vorschlagen, dieses Snippet einmal genauer anzuschauen.

Code:
// using System.Data.Odbc;
// using System.IO;

private DataTable GetTableFromCSV(string path)
{
    if (!File.Exists(path))
        throw new FileNotFoundException();
   
    FileInfo fileInfo = new FileInfo(path);
    DataTable dataTable = new DataTable();
    string connectionString = String.Format("Driver={{Microsoft Text Driver (*.txt; *.csv)}};Dbq={0};", fileInfo.DirectoryName);
    OdbcConnection connection = new OdbcConnection(connectionString);
    OdbcDataAdapter da = new OdbcDataAdapter(String.Format("select * from [{0}]",fileInfo.Name), connection);
    da.Fill(dataTable);
    return dataTable;
}

Damit liest man CSV (also Komma-getrennte-Textdateien) in eine DataTable ein.

Vielleicht hilft dir das schon weiter - du hast es scheinbar nur nicht Komma-getrennt sondern mit einem anderen Zeichen.

PS: Wenn unbedingt StreamReader, dabei kannst du das Trennzeichen auch noch mit angeben.

VG,
Mad
 
Zuletzt bearbeitet:
ok..
Stream Reader, weil die text datei sieht so wie eine tabelle auch:

==166-70-SA21 §=000EEA011 §+H011 §-EA1 §1 §Rittal §SZ4140.830 §SZ4140.830 §Systemleuchte LED
==166-70-SA21 §=000EEA011 §+H011 §-EA1 §1 §Rittal §SZ4140.830 §SZ4140.830 §Systemleuchte LED
==166-70-SA21 §=000EEA011 §+H011 §-EA1 §1 §Rittal §SZ4140.830 §SZ4140.830 §Systemleuchte LED
==166-70-SA21 §=000EEA011 §+H011 §-EA1 §1 §Rittal §SZ4140.830 §SZ4140.830 §Systemleuchte LED

und so weiter.

habe mir überlegt wegen die trennung das zu benutzen:

Code:
string[] strS = s.Split(new Char[] { '§' });
 
Hi,

naja, das Format bedingt nicht den StremReader, aber egal.

habe mir überlegt wegen die trennung das zu benutzen

Ja dann mach das doch :) Kannst du bei den Snippets ja benutzen, die ich gepostet habe. Besonders beim Zweiten.

VG,
Mad
 
Hi Parrain,

deine File.Exists und while(!sr.EndOfStream) haben leider gar keinen Effekt.

Außerdem brauchst du keinen Streamreader; sofern es sich um eine Textdatei handelt (nicht unbedingt .txt als Endung, aber als Text Encodiert) kannst du den Inhalt mit File.ReadAllText einlesen.

ich hab dir mal eine kleine Funktion gebastelt:

Code:
private DataTable fillDataTableFromFile(string path)
        {
            DataTable dTable = new DataTable();

            if (File.Exists(path))
            {

                string fileText = File.ReadAllText(path);
                string[] fileLines = fileText.Split('§');

                foreach (string s in fileLines)
                {
                    dTable.Rows.Add(s);
                }
                return dTable;
            }
            else
            {
                MessageBox.Show("File does not exist!");
                return null;
            }

        }

Bei Fragen kannst du dich gerne melden ;-)

Viele Grüße
Zargos
 
String Operationen sind sehr rechenaufwändig.
Bei großen Datensätzen wird die Performance nicht so berauschend sein
 
SymA schrieb:
String Operationen sind sehr rechenaufwändig.
Bei großen Datensätzen wird die Performance nicht so berauschend sein

Das ist natürlich richtig ;-) Dennoch ist es ein sehr einfacher und praktischer Ansatz - leicht zu verstehen auch für "Anfänger"
 
Zuletzt bearbeitet:
zargos schrieb:
Das ist natürlich richtig ;-) Dennoch ist es ein sehr einfacher und praktischer Ansatz - leicht zu verstehen auch für "Anfänger"

War als Nebenbemerkung für den TE, nicht dass dieser sich später wundert, falls er große Datenmengen einließt, weshalb die Performance unter aller Sau ist.:D

Hatte persönlich auch schon das Problem:rolleyes:
 
oh..vielen danke für eure antworten :)


ich probier mal jetzt wie es laufen wird, und melde mich nochmal..was die Performance angeht, werde ich noch mal später schauen, da ich 3 verschieden Text datein einlesen möchte, und in der neue Tabelle eintragen.
Ergänzung ()

Hey, ich habe meinem Code jetzt mit der Hilfe von Zargos vorschlag, der für mich viel mehr sinn macht aufgebaut. eines jedoch habe ich nicht geändert, das DataTable defintion. weil es bei mir im Hauptprogramm (Form1) definiert. stimmt's dann so??

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;
using System.Windows.Forms;


namespace HWG2
{
    class Import
    {

        public DataTable ImportDaimlerBR205(DataTable dtWorkTable, string path)
        {

            if (File.Exists(path))                                  // Überprüfen ob Datei existiert
            {

                string fileText = File.ReadAllText(path);           //  lesen; öffnet die Datei, liest alle Zeilen und fügt die einzelnen in einen Stringarray
                string[] fileLines = fileText.Split('§');           //  Text Trennung in Text Datei

                foreach (string s in fileLines)                     // Schleife
                {
                    dtWorkTable.Rows.Add(s);                        // Einfügen von Reihen
                }
                return dtWorkTable;
            }

            else
            {
                MessageBox.Show(e.Message, "Datei nicht gefunden");   // Fehler Meldung
                return null;
            }
        }
    }
}

DataTable dtWorkTable ist dann als variable oben eingegeben.
 
Zuletzt bearbeitet:
Ja das geht natürlich.

Dann kannst du dir aber den Rückgabewert der Funktion sparen, da das Datatable-Objekt ja direkt in deiner Funktion "verarbeitet" wird.

--> die beiden "return" weg und die Funktion umbenennen in:

Code:
public void ImportDaimlerBR205(DataTable dtWorkTable, string path)

Außerdem hab ich auf meinem PC Schwierigkeiten mit dem "§"-Zeichen gehabt - es wurde nicht richtig eingelesen. Bei mir hat es geholfen das Encoding beim Dateieinlesen manuell auszuwählen und zwar mit:

Code:
string fileText = File.ReadAllText(path, Encoding.GetEncoding(1252));

Weitergehend muss dein DataTable natürlich schon mindestens eine Spalte haben. Wenn du ihn eh außerhalb initialisierst, solltest du das dort machen.

edit: den Rückgabewert MUSST du nicht ändern, wäre meiner Ansicht aber guter Stil, da du ihn nicht mehr benötigst.
 
ok mache dann so :)

was meinst du über den zugriff vom Form1.cs auf das Import.cs. fehlt da nicht etwas..

Code:
// Zugriff auf der DataTable
            xd.Load("" + (string)config.GetValue("TreeStartAdresse", typeof(string)) + "" + treeView1.SelectedNode.FullPath.Replace(treeView1.TopNode.Text, string.Empty) + "\\" + treeView1.SelectedNode.Text + ".xml");
            
            Import Text = new Import();             //Objekt vom typ Import definieren, um zugriff auf Import.cs zu ermöglichen 

            dtWorkTable = Text.ImportDaimlerBR205(dtWorkTable, xd.SelectSingleNode("Configuration/FileDirectory/txbGeräteliste").InnerText.ToString());

            ////                               (Tabelle      //   ,  // Pfad zu Gerätelistentext)         
         
         
           

            dataGridView1.DataSource = dtWorkTable;   //Tabelle anzeigen
Ergänzung ()

aha..jetzt bekomme eine fehler meldung im zugriff auf Import.cs als ich die funktion geändert habe wie du es mir gesagt hast.. (Konvertierung vom Typ void in ""System.Dat.dataTable ist nicht möglich ). ich glaube ich lasse's wie vorhin.
 
Zuletzt bearbeitet:
Hallo Parrain,

Der Teil
Code:
                string fileText = File.ReadAllText(path);           //  lesen; öffnet die Datei, liest alle Zeilen und fügt die einzelnen in einen Stringarray
                string[] fileLines = fileText.Split('§');           //  Text Trennung in Text Datei

                foreach (string s in fileLines)                     // Schleife
                {
                    dtWorkTable.Rows.Add(s);                        // Einfügen von Reihen
                }
funktioniert bei einer 4-zeiligen Beispieldatei
Code:
==166-70-SA21 §=000EEA011 §+H011 §-EA1 §1 §Rittal §SZ4140.830 §SZ4140.830 §Systemlampe
==167-80-SA22 §=000EEA012 §+H012 §-EA1 §1 §Rittal §SZ4140.830 §SZ4140.830 §Glühbirne
==168-90-SA23 §=000EEA013 §+H013 §-EA1 §1 §Rittal §SZ4140.830 §SZ4140.830 §Leuchtstoffröhre
==169-99-SA24 §=000EEA014 §+H014 §-EA1 §1 §Rittal §SZ4140.830 §SZ4140.830 §Systemleuchte LED
nicht richtig, er liefert 33 Zeilen und 1 Spalte.

Richtig wäre natürlich 4 Zeilen und 9 Spalten.

Mein Vorschlag (Ausschnitt):
Code:
            if (File.Exists(path))
            {
                using (StreamReader reader = new StreamReader(path))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        dtWorkTable.Rows.Add(line.Split('§'));
                    }
                }
......

Zudem muss natürlich die DataTable vorher mindestens schon 9 Spalten haben.
Dies erreicht man z.B. durch
Code:
            dtWorkTable.Columns.Add("c1"); // wähle einen passenderen Namen
            dtWorkTable.Columns.Add("c2");
            dtWorkTable.Columns.Add("c3");
            dtWorkTable.Columns.Add("c4");
            dtWorkTable.Columns.Add("c5");
            dtWorkTable.Columns.Add("c6");
            dtWorkTable.Columns.Add("c7");
            dtWorkTable.Columns.Add("c8");
            dtWorkTable.Columns.Add("c9");
bei der Initialisierung von "dtWorkTable".


HTH

BigNum
 
Hi BigNum, schön das du wieder da bist :)

meine Tabelle sieht so aus:
Code:
  //Tabelle einlesen
            #region - Definition WorkTable -           
           
            dtWorkTable.Columns.Add("Gerätenummer");     //
            dtWorkTable.Columns.Add("Hersteller");       // Siemens; Phoenix
            dtWorkTable.Columns.Add("Bestellnummer");    // 5S4104-7
            dtWorkTable.Columns.Add("Gerätetyp");        // 5SY4                  
            dtWorkTable.Columns.Add("IP-Adresse");       // 196.245.098.16
            dtWorkTable.Columns.Add("Subnetzmaske");     // 255.255.255.255
            dtWorkTable.Columns.Add("RouterAdresse");    //            

            #region - Position -
            dtWorkTable.Columns.Add("Pos_X");            // X-Koordinate
            dtWorkTable.Columns.Add("Pos_Y");            // Y-KOordinate
            #endregion
          
            #region - E_Parameter -
            dtWorkTable.Columns.Add("E");                // Eingangsparameter (Eingangsadresse)
            #endregion

            #region - A_Parameter -
            dtWorkTable.Columns.Add("A");                // Ausgangsparameter (Ausgangsadresse)
            #endregion

          
            #region - F_Parameter -
            dtWorkTable.Columns.Add("F_SIL");            //
            dtWorkTable.Columns.Add("F_CRC_Length");     //
            dtWorkTable.Columns.Add("F_Block_ID");       //
            dtWorkTable.Columns.Add("F_Par_Version");    //
            dtWorkTable.Columns.Add("F_Source_Add");     //            
            dtWorkTable.Columns.Add("F_Dest_Add");       //
            dtWorkTable.Columns.Add("F_WD_Time");        //
            dtWorkTable.Columns.Add("F_iPar_CRC");       //                      
            #endregion

            #region - Ort BMK -
            dtWorkTable.Columns.Add("Ort");              // +H011
            dtWorkTable.Columns.Add("BMK");              // -EA1
            #endregion

            #endregion

die zu lesene Datei hat viel zeilen..ich versuche nochmal mit deinen Vorschlag
 
Zuletzt bearbeitet:
Parrain schrieb:
meine Tabelle sieht so aus

Dann würde ich es so machen (Ausschnitt):
Code:
                using (StreamReader reader = new StreamReader(path))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        DataRow row = dtWorkTable.NewRow();
                        string[] sa = line.Split('§');
                        row["Ort"] = sa[0]; // hier natürlich die richtige Zuordnung
                        row["BMK"] = sa[1]; // hier natürlich die richtige Zuordnung
                        row["F_SIL"] = sa[2]; // hier natürlich die richtige Zuordnung
                        ... usw.
                        dtWorkTable.Rows.Add(row);
                    }
......
Also für jeden Teil einer Zeile (mit "§" getrennt) die entsprechende Spaltenbezeichnung (z.B. "BMK").


HTH

BigNum
 
Hallo BigNum,

es klappt super :) Text wird in meiner neue Tabelle eingelesen..habe jedoch noch eine kleinigkeit. oder besser gesagt 2 fragen. der neu code sieht so aus:
Code:
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;
using System.Windows.Forms;


namespace HWG2
{
    class Import
    {

        public DataTable ImportGeräteliste(DataTable dtWorkTable, string path)
        {

            if (File.Exists(path))                                        // Überprüfen ob Datei existiert
            {
                using (StreamReader sr = new StreamReader(path, Encoding.Default))
                {
                    string line;                                          // 
                    while ((line = sr.ReadLine()) != null)                //  Schleife
                    {
                        
                        
                        string[] strS = line.Split(new Char[] { '§' });  // Spalten Trennung
 
                        if (strS[0] != string.Empty)                     // Leere Zeile Rausschneiden
                        {
                        DataRow row = dtWorkTable.NewRow();              // Neue Zeile Definieren

                        row["Hersteller"] = strS[5].Trim();                     // Einträge eintragen und Leerraumzeichen entfernen
                        row["Bestellnummer"] = strS[6].Trim();                  // Einträge eintragen
                        row["Gerätetyp"] = strS[7].Trim();                      // Einträge eintragen

                       

                        dtWorkTable.Rows.Add(row);                        //  Einfügen von Reihen
                        }
                    }
                }
                return dtWorkTable;
            }

            else
            {
                MessageBox.Show("Datei nicht gefunden");                  // Fehler Meldung falls Datei nicht gefunden
                return null;
            }
        }

1. Frage: wie du es Oben siehst versuche eine leere zeile zu entfernen, klappt aber nicht mit:

Code:
 if (strS[0] != string.Empty)                     // Leere Zeile Rausschneiden
                        {


2. Frage: ich möchte jetzt die fehlende spalten von eine andere text datein einlesen und in der selbe Tabelle einfügen, ich werde fast das selbe code wie oben haben. auf was soll ich beachten beim einfügen??
 
Parrain schrieb:
1. Frage: wie du es Oben siehst versuche eine leere zeile zu entfernen, klappt aber nicht mit:
Dann versuch es mal mit
Code:
if (!string.IsNullOrEmpty(strS[0]))
Wenn das auch nicht funktioniert, musst Du mal den Debugger anwerfen und nachsehen welche Werte "strS" hat.
Das geht folgendermassen:
Du klickst im Source-Code auf die Zeile nach "if (!string.IsNullOrEmpty(strS[0]))" und drückst dann die "F9"-Taste. Nun sollte diese Zeile rot hinterlegt sein. Dann startest Du den Debugger mit "F5", der Code wird ausgeführt und stoppt die Ausführung vor der rot hinterlegten Zeile.

Jetzt fährst Du mit dem Mauszeiger über "strS" und wartest ca. 2 Sekunden, es erscheint ein kleines Popup-Fenster mit einem "+"-Zeichen gefolgt von "strS". Wenn Du nun auf das "+"-Zeichen fährst (wieder ca. 2 Sekunden warten) erscheint der Inhalt des "strS"-Arrays!

Nun so oft "F5" drücken bis die Leerzeile gelesen wird, dann wieder mit der Maus auf "strS" fahren, dann auf das "+" fahren und den Inhalt des Arrays betrachten und kontrollieren, warum "strS[0]" ungleich dem Leerstring ist ;)

Zum Schluß wieder auf die rot hinterlegte Zeile klicken und wieder "F9" drücken, dann wird der sog. "Breakpoint" wieder entfernt!

Parrain schrieb:
2. Frage: ich möchte jetzt die fehlende spalten von eine andere text datein einlesen und in der selbe Tabelle einfügen, ich werde fast das selbe code wie oben haben. auf was soll ich beachten beim einfügen??
Du solltest einen sog. "Primärschlüssel" (engl. primary key) für Deine Tabelle anlegen.
Ich gehe im Folgenden davon aus, daß dies die Bestellnummer ist:

In der Initialisierung Deiner Tabllel fügst Du folgenden Code ein:
Code:
DataColumn[] PrimaryKeyColumns = new DataColumn[1];
PrimaryKeyColumns[0] = dtWorkTable.Columns["Bestellnummer"];
dtWorkTable.PrimaryKey = PrimaryKeyColumns;
und beim Einfügen der anderen Spalten aus den anderen Dateien musst Du Dir die entsprechende Zeile mit
Code:
DataRow row = dtWorkTable.Rows.Find( Bestellnummer); // hier den String mit der Bestellnummer einfügen
statt
Code:
DataRow row = dtWorkTable.NewRow();
wie in der jetzigen Import-Methode suchen.

Das mit dem "primary key" findest Du auch im Beipspiel-Code von Microsoft unter

http://msdn.microsoft.com/en-us/library/9186hy08

bzw.

http://msdn.microsoft.com/en-us/library/system.data.datatable.primarykey


HTH

BigNum
 
hey BigNum, ich habe gerade dein nachricht gesehen. ich habe aber schon eine lösung für meine erste frage gefunden :) ich habe folgende code eingegeben bei der if anweisung:

Code:
if (strS[0].Trim() != "")

ich schaue nach der 2. frage und melde mich noch..ich bedanke mich sehr bei dir für deien hilfe :)
Ergänzung ()

Hey BigNum mit deinen vorschlag hat es nicht geklappt die zeile zu löschen, weil die zeile war eigentlich nicht leer..es sieht so aus:

==166-70-SA21 §=000EEA011 §+H011 §-EA1 §1 §Rittal

§ § § § §

==166-70-SA21 §=000EEA011 §+H011 §-EA1 §1 §Rittal

was ich am anfang übersehen habe ;)
 
Zurück
Oben