Probleme beim Datei einlesen mit C#

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Fortuna
User
Beiträge: 4
Registriert: Montag 3. September 2012, 10:37

Hallo,

ja der Titel ist nicht wirklich aussagekräftig aber derzeit fällt mir nichts anderes ein. Ich lese per StreamReader eine Datei und möchte sie zeilenweise überprüfen. Das ist soweit nicht das Problem, das Problem ist: Ich lese die Datei und lass mir zeilenweise den Inhalt ausgeben. Dabei zeigt sich, das ich nur vllt. 5-6 Zeilen ausgegeben bekomme und der Rest einfach übersprungen wird. Der Zeiger beginnt auch gar nicht bei der ersten Zeile sondern fängt einfach mal bei der 3 oder 4 an.

Ich versuche das mal in Stichworten zusammenzufassen (ich bin recht schlecht in Erklären):

Was soll gemacht werden?
1. Datei einlesen
2. Jede Zeile auf ein bestimmtes Muster überprüfen
3. Ergebnis in eine DataTable speichern

Problem
1. Der Zeiger beginnt, bei der eingelesenen Datei nicht in der 1. Zeile
2. Es werden nur wenige Zeilen gelesen, nicht alle

Aktueller Code
Anm: Wir benutzen IronPython

Code: Alles auswählen

def fp_AnalyseFiles(pDt1):
	try:
		DetailsBox.Show("Start der Dateianalyse.")
                #mStrStartPath enthält einen gültigen Pfad.
		DetailsBox.Show(mStrStartPath)
		dt1 = DataTable("Analyses")
		dt1.Columns.Add("number").AutoIncrement = True
		dt1.Columns.Add("incrementalpath")
		dt1.Columns.Add("line")
		dt1.Columns.Add("string")
		dt1.Columns.Add("filename")
		dt1.Columns.Add("extension")

		#Durchlaufen der DataTable pDt1.
		for row1 in pDt1.Rows:
			#Entfernen des ersten Backslashs und anschließendes Speichern in einer Variable
			strIncrementalPath = row1["incrementalpath"].Substring(1)
			#Zusammenfügen des Startpfads und des Inkrementalpfads
			strFile = Path.Combine(mStrStartPath, strIncrementalPath)
			#Überprüfen ob die Datei existiert.
			if File.Exists(strFile):
				#Datei öffnen und lesen.
				objFile = StreamReader(strFile)
				DetailsBox.Show(strFile)
				while objFile.ReadLine():
					#@TODO
					#Den Inhalt auf clr-Einträge per Regex überprüfen.
					#Muster des Regulären Ausdrucks. (NICHT FERTIG)
					#Das aktuelle Pattern matched "import clr" und alle Zeilen, die ein "clr.*" enthalten
					#Das Pattern wurde getestet und funktioniert.
					strPattern = r"^(import\sclr|clr\.[\w+]+\([a-z0-9\.\,\"]+\))$"
					objRegex = Regex(strPattern)
					#Beinhaltet die Anzahl an gefundenen Treffern.
					objMatch = objRegex.Match(objFile.ReadLine())
					DetailsBox.Show(objFile.ReadLine() + objMatch.Value)
					#Wenn Treffer gefunden wurden, lege eine neue Zeile an.
					if (objMatch.Success == True):
						row2 = dt1.NewRow()
						row2["incrementalpath"] = row1["incrementalpath"]
						row2["filename"] = row1["filename"]
						row2["extension"] = row1["extension"]
						dt1.Rows.Add(row2)
						
				objFile.Close()
		
		return dt1
				
	except Exception as ex:
		DetailsBox.Show(ex)
DetailsBox.Show() ist eine Firmeninterne Klasse und zeigt einfach einen Windowsdialog mit dem angegebenen Inhalt an. Die Fehlerbehandlung in Python ist halt der Oberwitz (zumindest bei uns im Betrieb). Es wird zwar ein Fehler angezeigt mit Stacktrace, aber die Zeilenangabe fehlt halt und man verbringt Stunden damit den Fehler einzukreisen...

Naja, ich hoffe mir kann geholfen werden :P

Danke und Gruß
Fortuna
Fortuna
User
Beiträge: 4
Registriert: Montag 3. September 2012, 10:37

Habs gelöst, komischerweise kommt die Lösung immer dann, wenn ich sie in einem Forum schreibe x_X

Lösung
Ich habe in der while-Schleife 3. ReadLine() ausgeführt, was dazu führte, dass jede 3. Zeile ausgelesen wird. Die Lösung war dann den Wert von ReadLine() in einer Variablen zu speichern.

Code ab File.Exists()

Code: Alles auswählen

if File.Exists(strFile):
				#Datei öffnen und lesen.
				objFile = StreamReader(strFile)
				DetailsBox.Show(strFile)				
				logLines = True
				while logLines:
					objLine = objFile.ReadLine()
					if objLine is None:
						logLines = False
					#@TODO
					#Den Inhalt auf clr-Einträge per Regex überprüfen.
					#Muster des Regulären Ausdrucks. (NICHT FERTIG)
					#Das aktuelle Pattern matched "import clr" und alle Zeilen, die ein "clr.*" enthalten
					#Das Pattern wurde getestet und funktioniert.
					strPattern = r"^(import\sclr|clr\.[\w+]+\([a-z0-9\.\,\"]+\))$"
					objRegex = Regex(strPattern)
					#Beinhaltet die Anzahl an gefundenen Treffern.
					objMatch = objRegex.Match(objLine)
					DetailsBox.Show(objLine + objMatch.Value)
					#Wenn Treffer gefunden wurden, lege eine neue Zeile an.
					if (objMatch.Success == True):
						row2 = dt1.NewRow()
						row2["incrementalpath"] = row1["incrementalpath"]
						row2["filename"] = row1["filename"]
						row2["extension"] = row1["extension"]
						dt1.Rows.Add(row2)
						
				objFile.Close()
Zuletzt geändert von Fortuna am Montag 3. September 2012, 11:44, insgesamt 1-mal geändert.
BlackJack

@Fortuna: Eigentlich ist das ja keine Python-Frage sondern eine .NET-Frage, denn von Python wird ausser der Syntax kaum etwas verwendet. Und ein Syntaxproblem ist es ja nicht.

`ReadLine()` „verbraucht” eine Zeile. Dass das so nicht gehen kann, müsste man durch ein bisschen nachdenken bemerken woher der Rechner denn eigentlich wissen können soll welches `ReadLine() eine Zeile weiter lesen soll und welches die zuletzt gelesene Zeile noch einmal liefern müsste, damit das wie gewünscht funktionieren würde.

Ich würde an der Stelle ja mal tatsächlich Python verwenden und mit dessen Mitteln die Datei verarbeiten. Sonst programmiert man am Ende nicht mit sondern eher gegen die Sprache.
Fortuna
User
Beiträge: 4
Registriert: Montag 3. September 2012, 10:37

Da hast Du sicher recht @BlackJack. Aber ich wurde letzten Donnerstag erst in Python "geworfen" und muss mich nach den Firma internen Strukturen richten. Ob das aktuell sinnvoll ist was ich da in Python baue, kann ich derzeit schlecht einschätzen. Bei ReadLine() habe ich mir auch an den Kopf gefasst.
BlackJack

@Fortuna: Man könnte wenigstens eine ``for``-Schleife daraus machen in dem man sich mit der `iter()`-Funktion ein iterierbares Objekt erstellt.

Code: Alles auswählen

from System.IO import StreamReader


def main():
    reader = StreamReader('test.txt')
    for line in iter(reader.ReadLine, None):
        print line
    reader.Close()


if __name__ == '__main__':
    main()
Der reguläre Ausdruck dürfte ein paar Zeichen kürzer geehen. Innerhalb von eckigen Klammern gelten andere Regeln. Zeichen die aussehalb eine besondere Bedeutung haben, verlieren diese in der Regel dort. Ein ``+`` ist dort zum Beispiel tatsächlich einfach nur ein Pluszeichen. Das hier reicht also:

Code: Alles auswählen

r'^(import\sclr|clr\.\w+\([a-z0-9.,"]+\))$'
Wobei sich da die Bedeutung jetzt auch leicht geändert hat, denn ``clr.a+b(c)`` wird nun nicht mehr erkannt — vorher schon.

Klammern um die Bedingung bei ``if`` sind unnötig und ein expliziter Vergleich mit einem literalen Wahrheitswert sollte man auch nicht machen. Bei dem Vergleich kommt doch eh nur wieder der gleiche Wert heraus, den das `Success`-Attribut sowieso schon hatte.

Was die Ausnahme im Fenster angeht, solltest Du nicht die Ausnahme selbst ausgeben, sondern Dir den Traceback erzeugen lassen. Das geht mit `traceback.format_exc()`. Dann siehst Du auch *wo* das Problem aufgetreten ist.
Antworten