Laden...

Textdatei auslesen und in einer Tabelle ausgeben

Erstellt von MisterMinister vor 13 Jahren Letzter Beitrag vor 13 Jahren 9.509 Views
M
MisterMinister Themenstarter:in
7 Beiträge seit 2010
vor 13 Jahren
Textdatei auslesen und in einer Tabelle ausgeben

Hallo zusammen.

Ich stehe vor einem Delikaten Problem,was auf meine unkenntniss und einfallslosigkeit zurückzuführen ist.

Situation:
Ich möchte eine Datei (Sie beinhaltet Reinen text und zahlen, allerdings schon fast tabellarisch) in einer Tabelle ausgeben,ohne auf Installierte Programme(bsp.Exel etc.) zurückzugreifen.

Erklärung: Die Datei ist bereits in einer art Tabelle zusammengefasst.Allerdings ist diese Tabelle recht unordentlich,weil die Spalten und Zeilen unterschiedlich sind.

Bsp.: Nr Spalte1 Spalte2 Spalte3
0 Spalte1+Wert Spalte2+Wert Spalte3+Wert

Wie man sehen kann,stehen in "Zeile0" Werte mit längerem Namen als die Spalte eigentlich erfassen kann/könnte.
Man könnte jetzt hergehen,und die Datei editieren,indem man mit TAB arbeitet,ist allerdings leider nicht möglich.
Dadurch,das diese Datei eine Aktive Rolle spielt,und permanent von einem anderen Programm benutzt wird,und keinerlei andere Formatierung(als die ursprüngliche) zulässt,kann man diese Datei leider nicht ordnen.

Ein weiteres Problem stellt die Codierung dar.Die Datei ist in Unix-Formatierung geschrieben.
Die Tabelle,die dann erstellst wurde,sollte beim nachträglichen bearbeiten die Text-formatierung, sowie die Codierung beibehalten.

Nun zu meiner Theorie:

Die von mir erstellte Application sollte die Codierung,und auch die Text-formatierung erkennen (wegen den leerzeichen,Tabs,Zeilenabstände,Spaltenabstände ), in einer Tabelle "geordnet" ausgeben, zu bearbeiten sein,und dann wieder im ursprungsformat (Unix und Text-format) gespeichert werden können.Wichtig dabei wäre noch zu erwähnen..Die Länge der Wörter werden sich nicht verändern.War ein wort mit einer länge von 8 Buchstaben in einer Zeile,so wird das neue Wort wieder genau 8 Buchstaben haben.

Hier ein Beispiel wie so eine Tabelle in dieser Datei aussieht.
In diesem Beispiel sind die Spaltennamen länger wie Werte die in dieser Spalte stehen.


[NpcPos]	Flags	Index	PosX	PosY	Type	IsRangeCheck
0        0	1	36	41	3	1
1        0	2	37	36	2	1
2        0	3	37	13	5	1
3        0	4	18	13	1	1

Wie gesagt.Die Formatierung und die Codierung sind dabei sehr wichtig,und dürfen in der Grundstrucktur nicht verändert werden.sonst wird diese Datei unbrauchbar.
Nur in der Application sollen die angezeigten Werte den zugehörigen Spalten zugeordnet werden.

Meine Bemühungen:
Google gibt ne menge Daten über die DataGrid methode raus,wo ich allerdings nicht ganz durch-steige.In vielen beispielen wird die Textdatei umformatiert (meistens zu XML) und dann in die Tabelle geladen.
Oder es wird auf bereits Installierte Programme zurückgegriffen( ExelWorkSheet).
Da nicht jeder, der diese Application benutzt/benutzen könnte Exel oder andere Tabellen-Programme installiert hat(wovon man ausgehen muss) ist es auch wichtig,das es in einer "programm-internen" Tabelle Dargestellt wird.

Ich hoffe,ich habe keine Information vergessen und habe nicht zu viel dummes zeug gequatscht.

Und da ich nicht einer derjenigen bin die "Gib mal" "Schreib mal" "Mach mal" Posten,Hoffe ich auf ein paar Denkanstöße und eventuell Links zu ähnlichen Themen,die mir das Wissen darüber vermitteln können.Klingt zwar auch etwas nach "Gib mal" "Schreib mal" "Mach mal",aber mit dem unterschied,das ich wahrscheinlich einfach die falschen Schlagwörter bei google benutze.

Danke jetzt schonmal im Vorraus für die bemühungen und Antworten.

P.S. kann ich jede Datei laden,die Text enthält,oder muss man dem Programm klipp und klar sagen,wie er mit welcher Datei zu verfahren hat ?
Die Datei-Endung ist nicht "txt".

R
68 Beiträge seit 2010
vor 13 Jahren

So etwas lässt sich relativ einfach mit dem System.IO.File namespace,
ein bischen Stringverarbeitung und ggf. regular expressions im Rahmen
einer Windows-Form App abfackeln. Aber wenn Du mit diesen Themen bisher
noch keinerlei Berührungspunkte hattest, ist es natürlich sehr schwierig.
Die Dateiendung spielt keine Rolle.

Da Du Excel erwähnt hast: Eine einfache VBA-App, die das File einliest
und in Exel darstellt geht nicht?

Robin

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo RBA285,

Da Du Excel erwähnt hast: Eine einfache VBA-App, die das File einliest
und in Exel darstellt geht nicht?

scheidet wegen

Da nicht jeder, der diese Application benutzt/benutzen könnte Exel oder andere Tabellen-Programme installiert hat(wovon man ausgehen muss) ist es auch wichtig,das es in einer "programm-internen" Tabelle Dargestellt wird.

wohl aus 😉

Hallo MisterMinister,

Ich stehe vor einem Delikaten Problem,was auf meine unkenntniss und einfallslosigkeit zurückzuführen ist.

Haha...

Die Datei ist in Unix-Formatierung geschrieben.

Die Zeilenenden werden in Unix per \n und in Windows per \r\n markiert. D.h. auch unter Windows kann ein Zeilenende mit \n erkannt werden und somit stellen Unix-Dateien beim Lesen kein Problem dar.

Beim Schreiben kann entweder Zeile für Zeile unter Angabe von \n geschrieben werden oder beim StreamWriter wird die NewLine-Eigenschaft entsprechend auf \n gesetzt.

Damit aus einer Zeile auch Spalten gelesen werden können muss die Zeile anhand eines Trennzeichens aufgeteilt werden. Wenn wie in deinem Beispiel das Trennzeichen ein Leerzeichen ' ' ist dann ist die Sache einfach - auch in Hinblick auf das Schreiben der Datei. Andernfalls wirds schwieriger, denn dann müssten die Anzahl/Typ der Trennzeichen irgendwo zwischengespeichert werden.

Um die Daten in einer Tabelle anzuzeigen empfiehlt es sich die Zeilen in Objekte zu lesen und diese per Datenbindung in der UI anzuzeigen und bearbeitbar machen.

Soviel zu meiner Theorie 😉 Nun ein wenig Code der dir auf die Sprünge helfen soll - angelehnt an deine Beispieldaten.


public class DataItem
{
	public string Nr { get; set; }
	public string Spalte1 { get; set; }
	public string Spalte2 { get; set; }
	public string Spalte3 { get; set; }
}


private static IEnumerable<DataItem> ReadColumns(StreamReader sr)
{
	while (!sr.EndOfStream)
	{
		string line = sr.ReadLine();
		string[] cols = line.Split(' ');
		yield return new DataItem
		{
			Nr = cols[0],
			Spalte1 = cols[1],
			Spalte2 = cols[2],
			Spalte3 = cols[3]
		};
	}
}


private static void WriteColumns(StreamWriter sw, string header, IEnumerable<DataItem> data)
{
	// Kopfzeile schreiben:
	sw.WriteLine(header);

	// Daten schreiben:
	foreach (DataItem item in data)
		sw.WriteLine("{0} {1} {2} {3}", item.Nr, item.Spalte1, item.Spalte2, item.Spalte3);
}


string header = null;
List<DataItem> data = null;

using (StreamReader sr = File.OpenText("Daten.txt"))
{
	// Kopfzeile lesen:
	header = sr.ReadLine();

	// Daten lesen:
	data = ReadColumns(sr).ToList();
}

// Datenbindung von inhalt, etc.

using (StreamWriter sw = File.CreateText("Daten1.txt"))
{
	// Wegen Unix die NewLine setzten:
	sw.NewLine = "\n";

	WriteColumns(sw, header, data);
}

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

M
MisterMinister Themenstarter:in
7 Beiträge seit 2010
vor 13 Jahren

Hallo Ihr beiden.

Danke für eure antworten.

@gfoidl
Dein Codebeispiel sieht ja schonmal sehr gut aus.
Ich werde mich natürlich sofort daran setzen,und mit deinem Denkanstoß die Theorie in die Praxis umsetzen.

Danke nochmals.

Mfg

MM

M
MisterMinister Themenstarter:in
7 Beiträge seit 2010
vor 13 Jahren

Hallo nochmal..

Tut mir wirklich leid das ganze nochmal auf zu rollen.
Aber. Leider kommt mir bei der ganzen sache dann doch noch nen kleiner Fehler.

folgendes hab ich bereits gelöst:

StreamReader myFile = new StreamReader(path);
                    // Die ersten 66 Zeilen überspringen----Skip first 66 lines
                    for (int i = 0; i < 67; i++) { myFile.ReadLine(); }
                    string[] values = myFile.ReadLine().Split('\t');
                    while (values != null)
                    {
                        int row = dataGridView1.Rows.Add();
                        for (int i = 0; i < values.Length - 1; i++)
                        {
                            dataGridView1.Rows[row].Cells[i].Value = values[i];
                        }
                        values = myFile.ReadLine().Split('\t');

Das zeigt mir meine Datei im DataGridView an,ohne Fehler.
Bearbeiten kann ich das ganze natürlich auch.

Nun stehe ich vor dem Speichern.

Ich gehe strikt dem Beispiel von gfoidl vor.

using (StreamWriter sw = File.CreateText("Daten1.txt"))
{
    // Wegen Unix die NewLine setzten:
    sw.NewLine = "\n";

    WriteColumns(sw, header, data);
}

Wobei ich sagen muss,das ich mit einem Button die geänderten Werte wieder speichern will.
Demnach sieht der Code im moment entsprechend so aus:

private void button3_Click(object sender, EventArgs e)
        {
            using (StreamWriter sw = File.CreateText("Data1.txt"))
            {
                sw.NewLine = "\n";
                sw.WriteLine();

Das Problem iss nun,das er zwar die neue Datei (Datei1.txt) erstellt,aber dort nichts reinschreibt.
weder Collumnen,noch Lines..

langsam aber sicher vermute ich,das mir da ein Fehler unterlaufen iss,den ich nicht sehen kann.
[Ironie]Ich erinnere nochmal daran,das ich im moment noch nicht so gut bin was C# angeht.Und die suche bei google gibt immer nur CSV oder XML raus.[/Ironie]

Ich hoffe,ihr könnt mir nochmals helfen.
Danke im Vorraus.

Mfg

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo,

Das Problem iss nun,das er zwar die neue Datei (Datei1.txt) erstellt,aber dort nichts reinschreibt.
weder Collumnen,noch Lines..

Dein Code schreibt auch nur eine leere Zeile hinein. Schau dir nochmal mein obiges Beispiel an. Dort wird die Methode WriteColumns aufgerufen - das sollte auch in deinem Code passieren.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

M
MisterMinister Themenstarter:in
7 Beiträge seit 2010
vor 13 Jahren

Auch wenn ich Gefahrlaufe als Dummbeutel da zu stehen(was zweifellos schon geschehen ist).

Ich glaube ich kapier das nicht.
Dein Code macht Sinn.Das steht ausser Frage.

Die frage ist halt nur,wie ich deinen Code in meinen schon existierenden Code mit einbaue.

Ich werde mal meinen gesamten bisher geschriebenen Code Posten(am ende des Posts).
Ich wäre sehr dankbar,wenn du dir die mühe machen würdest/willst/möchtest, diesen mit deinem zu ergänzen.

Denn ich Blick da im moment so ziemlich gar nicht mehr durch (obwohl es mein eigener Code ist X( )

Falls ich damit zu Aufdringlich bin,tut es mir leid,und wäre auch nciht enttäuscht,wenn es nicht machbar ist.

Mfg,

MM

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.IO;
using System.Collections;
using System.Diagnostics;

namespace DataGrid
{
    public partial class Form1 : Form
    {
        string path = null;


        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            // Displays an OpenFileDialog so the user can select a File.
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "txt Files|*.txt";
            openFileDialog1.Title = "Select Target";

            // Show the Dialog.
            // If the user clicked OK in the dialog and
            // a .txt file was selected, open it.
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                textBox1.Text = openFileDialog1.FileName;
            }


        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            path = textBox1.Text;

        }

        private void button2_Click(object sender, EventArgs e)
        {
            
            //Prüfen, ob die Datei existiert:
            try
            {
                if (File.Exists(@path))
                {
                    //Process.Start(@path);
                    StreamReader myFile = new StreamReader(path);
                    // Die erste 66 Zeilen überspringen----Skip first 66 lines
                    for (int i = 0; i < 67; i++) { myFile.ReadLine(); }
                    string[] values = myFile.ReadLine().Split('\t');
                    while (values != null)
                    {
                        int row = dataGridView1.Rows.Add();
                        for (int i = 0; i < values.Length - 1; i++)
                        {
                            dataGridView1.Rows[row].Cells[i].Value = values[i];
                        }
                        values = myFile.ReadLine().Split('\t');
                    }

                }
            }

            catch (Exception ex)
            {
                /*MessageBox.Show(String.Format("An error has occured:\n{0}", ex.Message));
                path = null;*/
            }
        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            MessageBox.Show(".::Secret Squirrel::.  \nand\n .::MoroccoMole::.");
        }

        private void button3_Click(object sender, EventArgs e)

        {
            using (StreamWriter sw = File.CreateText("Data1.txt"))
            {
                sw.NewLine = "\n";
                


                }
        }
    }
}
6.911 Beiträge seit 2009
vor 13 Jahren

Hallo,

diesen mit deinem zu ergänzen.

Naja, mein Code besteht aus Klassen und Methoden und diese per Copy & Paste in dein Projekt zu transferieren kannst du selber 😁

Warum weichst du in deinem Code von dem von mir vorgeschlagenen Weg1.Einlesen der Daten aus der Textdatei in Objekte 1.die Objekte per Datenbindung im DGV darstellen 1.die Objekte wieder in die Textdatei schreiben

ab? Du machst es dir nur unnötig kompliziert. Ich empfehle bei dem oben beschriebenen Vorgehen zu bleiben.

Lies und denk dir die obigen Antworten nochmals durch.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"