Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
textdatei rückwärts lesen
Afrokalypse
myCSharp.de - Member



Dabei seit:
Beiträge: 452

Themenstarter:

textdatei rückwärts lesen

beantworten | zitieren | melden

hi leute,
gibt es eine möglichkeit von unten nach oben in einer textdatei zu lesen?

hab bei streamreader / textreader etc... jetzt auf anhieb nichts gefunden oder vllt übersehen.... und hier über die suche auch nicht.

mfg
Afr0
Signatur:
Die Signatur wird unter Ihren Beiträgen dargestellt.

:O ?( 8) ;( 8o :] =) X( :rolleyes: :baby: :evil: :tongue:
Smilies find ich doof =]
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8.746
Herkunft: Berlin

beantworten | zitieren | melden

Lustig. Ein Stream ist etwas, wo jemand etwas reinsteckt, und ein anderer holt es wieder raus. Man kann sich das als Röhre vorstellen.

Deine Frage bedeutet übertragen, dass man das, was als letztes in das Rohr gesteckt werden soll (noch nicht passiert!), rausholt, noch bevor es reingesteckt wurde. Quantenphysik also.

Im Prinzip sind Streams also FIFOS, bzw. Pipes.

Bei MS hat das Konzept ordentlich verwuschelt, weil Streams dort auch Direktzugriff erlauben und die Abfrage der Länge ermöglichen, allerdings nicht immer (NotSupportedException). Mal davon abgesehen, dass MS hier ein grottenhafte Vererbung hingelegt hat (Methoden die nur bei bestimmten Subklassen funktionieren... damit fällt jeder Studi durch seine SE-Prüfung), hättest du also bei FileStreams die Chance die Länge abzufragen, mittels Seek() an die entsprechend Stelle zu gehen, ein Zeichen (!) zu lesen und dann den Cursor weiter nach vorne zu setzen.

Zwar ist FileStream gepuffert, aber du kannst wetten, dass die Pufferung nur für den Seek-Wert aufwärts implementiert ist. Damit ist beim Rückwärtslesen die Performance vermutlich um den Faktor 100-1000 langsamer als beim Vorwärtslesen.

Du solltest daher - wenn möglich - das File komplett in einen MemoryStream lesen und auf diesem rückwärts arbeiten. Am besten verkapselt über einen ReverseStreamReader.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo zusammen,

das mit dem MemoryStream oder ReverseSreamReader würde ich nicht machen. Je nachdem ob mal alle Zeichen oder alle Zeilen rückwärts lesen will, würde ich mit StreamReader.ReadToEnd ().Revese () einlesen oder eben mit File.ReadAllLines ().Reverse ().

herbivore
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8.746
Herkunft: Berlin

beantworten | zitieren | melden

Gute Idee, aber ReadToEnd() würde ich vermeiden, denn das verdoppelt nochmal den Speicherbedarf: ReadToEnd() erzeugt einen String, der das gesamte File aufnimmt, Reverse() einen weiteren.

Bei ReadAllLines() wird ja ein Array erstellt, welches durch Reverse() nur umsortiert wird. Da ist das also unkritisch.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo svenson,

kommt darauf an, wie groß die Datei ist. Nach meiner Erfahrung muss eine Datei schon ziemlich groß sein (auf jeden Fall > 100 MB) bevor die bequeme Programmierung anfängt spürbar zu werden.

herbivore
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8.746
Herkunft: Berlin

beantworten | zitieren | melden

Keine Frage.
private Nachricht | Beiträge des Benutzers
Afrokalypse
myCSharp.de - Member



Dabei seit:
Beiträge: 452

Themenstarter:

beantworten | zitieren | melden

hallo ihr beiden
danke erstmal für die ausführlichen antworten.
zu der größe: es können durchaus textdateien mit 300mb sein. von daher möchte ich diese nicht komplett in dem speicher halten.

die idee war eigentlich so, dass ich zB einen zeiger auf die letzte zeile in der datei setze.
aber wenn ich euch richtig verstanden habe, komme ich nicht um das einlesen der kompletten datei herum, oder?
Zitat
...hättest du also bei FileStreams die Chance die Länge abzufragen, mittels Seek() an die entsprechend Stelle zu gehen, ein Zeichen (!) zu lesen und dann den Cursor weiter nach vorne zu setzen.

ich hab die möglichkeit, die größe der datei abzufragen. wäre es dann nicht möglich meinen reader an das letzte byte in der datei zu setzen?
Signatur:
Die Signatur wird unter Ihren Beiträgen dargestellt.

:O ?( 8) ;( 8o :] =) X( :rolleyes: :baby: :evil: :tongue:
Smilies find ich doof =]
private Nachricht | Beiträge des Benutzers
plongo
myCSharp.de - Member



Dabei seit:
Beiträge: 123
Herkunft: RLP

beantworten | zitieren | melden

und wenn du jetzt hingehst und jeweils den letzen Eintrag in deine Datei jeweils in die erste Zeit schreibst statt in die letzte (also kein normales Anhängen)?

So stehen jeweils die letzten Beiträge an erste Stelle und du kannst normal vorwärts lesen. Eine chronologische absteigende Sotierung.
Gruss plongo

---------------------------------------------------------------------------
Woher soll ich wissen, was ich denke, bevor ich höre, was ich sage!
Kurzum: Läufer sind gesünder, "gescheiter" und glücklicher als Nichtläufer.
www.andreas-nicole.de
private Nachricht | Beiträge des Benutzers
Afrokalypse
myCSharp.de - Member



Dabei seit:
Beiträge: 452

Themenstarter:

beantworten | zitieren | melden

hallo plongo,
ich verstehe nicht ganz wie du das meinst.
ich muss ja erstmal an die letzte zeile meiner datei herankommen. wenn ich da bin wird der rest wahrscheinlich nicht so schwer werden.
Signatur:
Die Signatur wird unter Ihren Beiträgen dargestellt.

:O ?( 8) ;( 8o :] =) X( :rolleyes: :baby: :evil: :tongue:
Smilies find ich doof =]
private Nachricht | Beiträge des Benutzers
norman_timo
myCSharp.de - Member

Avatar #avatar-1775.jpeg


Dabei seit:
Beiträge: 4.506
Herkunft: Wald-Michelbach (Odw)

beantworten | zitieren | melden

Hallo Afrokalypse,

ich denke plongo meint, wenn Du Einfluß auf die Erstellung der Datei hättest, dass Du dann von vornherein Deine Einfügen Operationen revers gestaltest, also neuester Eintrag ganz vorne, und ältester Eintrag ganz hinten...

Das aber geht nur, wenn Du die Datei auch selbst erstellst.

Gruß
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
private Nachricht | Beiträge des Benutzers
plongo
myCSharp.de - Member



Dabei seit:
Beiträge: 123
Herkunft: RLP

beantworten | zitieren | melden

Genau so habe ich es gemeint. Damit hättest du ja die Probleme in der Performance beim rückwärtes lesen nicht mehr.

Die Andere Frage ist natürlich wie du dies programmierst das der letzte Eintrag in deiner Datei an erste Stelle stehst und dann erst die älteren Beiträge.
Gruss plongo

---------------------------------------------------------------------------
Woher soll ich wissen, was ich denke, bevor ich höre, was ich sage!
Kurzum: Läufer sind gesünder, "gescheiter" und glücklicher als Nichtläufer.
www.andreas-nicole.de
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Afrokalypse,

du kannst - ein entsprechendes Encoding vorausgesetzt, dass das Lesen an einer beliebigen Stelle erlaubt - die Datei blockweise einlesen, also z.B. die letzten 100kb, dann die vorletzten 100kb usw. und dann jeweils auf die Blöcke Reverse anwenden. An den Blockgrenzen muss man noch etwas aufpassen, aber sonst sollte es gehen.

Warum musst du denn die Datei überhaupt rückwärts einlesen? Vielleicht muss man das ja gar nicht.

herbivore
private Nachricht | Beiträge des Benutzers
sheitman
myCSharp.de - Member



Dabei seit:
Beiträge: 1.047

beantworten | zitieren | melden

hm, wie kann man denn dann z.b. einen stream von daten aus dem internet wirklich komplett lesen? größe abfragen geht ja nun mal nicht... und wenn der datenstrom mal "abreist" kann ich mir ja dann garnicht sicher sein ob das nun alles war oder nicht... da ich ja nicht wieß wir lang der strom eigentlich ist.... o.O
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo sheitman,

mein Vorschlag funktioniert natürlich nur bei Strömen, auf die man wahlfreien Zugriff (random access) hat. Einen Strom, denn man nur sequentiell lesen kann, muss man immer komplett lesen, bevor man ihn (bzw. seinen Inhalt) umdrehen kann.

herbivore
private Nachricht | Beiträge des Benutzers
sheitman
myCSharp.de - Member



Dabei seit:
Beiträge: 1.047

beantworten | zitieren | melden

und wie liest man so einen strom komplett?

stell dir vor du lädst eine datei aus dem internet runter... woher weißt du denn wann diese wirklich zu ende ist?

die größe des stromes wird man ja schlecht ermitteln können... und nur testen ob nun was gelesen wurde oder nicht heißt ja nun nicht umbedingt das die datei zuende ist... kann ja auch grad verbindungsprobleme geben... o.O
private Nachricht | Beiträge des Benutzers
norman_timo
myCSharp.de - Member

Avatar #avatar-1775.jpeg


Dabei seit:
Beiträge: 4.506
Herkunft: Wald-Michelbach (Odw)

beantworten | zitieren | melden

Hallo sheitman,

gerade im Internet wird im HTTP Header die Content-Length mit angegeben, besonders wenn es sich um herunterladbare Dateien handelt ;-)

Ich vermute mal dass überall, wo diese Information benötigt wird (Http, Ftp oder sonst irgendwas) die Größe vorab ermittellbar sein muss.

Gruß
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
private Nachricht | Beiträge des Benutzers
Afrokalypse
myCSharp.de - Member



Dabei seit:
Beiträge: 452

Themenstarter:

beantworten | zitieren | melden

hallo leute
sorry dass ich mich erst so spät wieder melde aber bin arbeitstechnisch ein wenig ausgelastet ^^

also: @herbivore: ich muss die datei rückwärts lesen, weil es sich um eine log-datei handelt und die letzten einträge zuerst in meinem programm aufgelistet werden sollen.

das ganze soll in form einer 2thread architektur gelöst werden. dabei wird thread1 an das ende der datei gesetzt und thread2 rückwärts durch die datei laufen. t1 kann t2 beliebig starten und stoppen.

so soll im endeffekt nur ein gewisser teil der datei geladen werden und gleichzeitig die position in der datei festgehalten werden.
Signatur:
Die Signatur wird unter Ihren Beiträgen dargestellt.

:O ?( 8) ;( 8o :] =) X( :rolleyes: :baby: :evil: :tongue:
Smilies find ich doof =]
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Afrokalypse,

ok, dann fällt mir auch keine andere Lösung ein als die genannten.

herbivore
private Nachricht | Beiträge des Benutzers
Afrokalypse
myCSharp.de - Member



Dabei seit:
Beiträge: 452

Themenstarter:

beantworten | zitieren | melden

hi leute
beim rückwärts lesen der datei ergeben sich bei mir einige problemchen


StreamReader sr = new StreamReader(@"c:\bla.txt",Encoding.Default);
char[] text = new char[1024];

for (long offset = sr.BaseStream.Length - text.Length; offset > -1; offset -= text.Length)
{
sr.BaseStream.Seek(offset, SeekOrigin.Begin);
sr.ReadBlock(text, 0, text.Length);
//consolenausgabe oder so
}

dass die datei so nicht komplett geladen werden kann ist mir wohl bewusst

mir geht es erstmal um etwas anderes:

wie man sieht lese ich immer einen block von 1024 zeichen. wenn ich diese ausgeben will dann stehen die blöcke verkehrt herum untereinander was den sinn des textes total durcheinander bringt^^. allerdings muss ich halt mit dem letzten block anfangen und mit dem ersten aufhören.

ich würde gerne zeilenweise arbeiten. hat da jemand ne idee wie sich das umsetzen lässt?
Signatur:
Die Signatur wird unter Ihren Beiträgen dargestellt.

:O ?( 8) ;( 8o :] =) X( :rolleyes: :baby: :evil: :tongue:
Smilies find ich doof =]
private Nachricht | Beiträge des Benutzers
Afrokalypse
myCSharp.de - Member



Dabei seit:
Beiträge: 452

Themenstarter:

beantworten | zitieren | melden

ok ich bin ein holzkopf

ich denke mal anders als dass ich den block in nen string array packe und nach \n unterteile wirds halt nicht gehen^^ ich dachte da gäbe es noch ne andere möglichkeit.... oder gibts doch eine?
Signatur:
Die Signatur wird unter Ihren Beiträgen dargestellt.

:O ?( 8) ;( 8o :] =) X( :rolleyes: :baby: :evil: :tongue:
Smilies find ich doof =]
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Afrokalypse,

String.Split zusammen mit Array.Reverse. Aber vielleicht meintest du das sowieso.

herbivore
private Nachricht | Beiträge des Benutzers