Einfügen von Text in eine vorhandene Datei an einer bestimmten Stelle
-
Servus zusammen,
ich habe hier gerade ein kleines Problem.
Ich muss in einer vorhandenen Datei einen Text aus einer anderen Datei einfügen.
Das Einfügen muss an einer bestimmten stelle geschehen.Lösungsansatz:
Öffne die Quelldatei und suche nach der Einfügestelle. Merke dir den offset zum Beginn der Datei über streamWriter.BaseStream.Position. Die Datei wird zeilenweise eingelesen. Öffne Datei zum Schreiben und navigiere zur Einfügestelle via baseStream.Seek(offset, SeekOrigin:Begin).Nun habe ich aber das Problem, dass der Text nach der Einfügestelle überschrieben wird. Das möchte ich nicht. Der vorhandene Text soll quasi weiter nach unten in der Datei wandern. Dachte immmer, das geht automatisch. Dem scheint wohl nicht so zu sein.
Das ganze Einlesen der Datei und erneutes rausschreiben der Datei kommt nicht in Frage, da die Datei zu groß ist.
Hat jemand eine Lösung oder Hilfestellung?
-
Weisst du um wieviel die Datei am ende größer wird ? Wenn ja: Fange dann von hinten an, so überschreibst du nur was du schon verarbeitet hast. Falls das rückwärtslesen probleme bereitet ist du zunächst die Daten in der Datei "verschieben" also den entsprechenden Offset vorne erzeugen.
kannst du sonst nicht das Ergebnis in eine dritte Datei ausgeben?
-
Nun ja, ich weiß was ich reinschreiben möchte. Also ja.
Kannst du mir sagen, wie ich die Datei vergrößere?Nehmen wir mal an, ich habe den neuen Inhalt in einem string oder stringbuilder.
Dann kann ich ja die Anzahl der Bytes bestimmen, die hinzukommen. Dabei muss ich dann ja noch \r\n mit 2 Bytes je Zeile berücksichtigen.
Insgesamt ist es halt nicht schön, geht aber.
-
Wie groß ist denn die Datei wenn ich Fragen darf?
-
Ich beziehe mich auf eine herkoemliche Festplatte:
nach meiner Auffassung ist das u.a. ein physikalisches Problem, denn eine Datei wird physikalisch sektorweise auf die Platte geschrieben. Wenn ich etwas mittendrin einfuegen will, muesste ich in der Lage sein physikalisch die Sektorenkette aufzubrechen. Da stellt sich schon das Problem, dass ein Sektor (=512 Nutzbytes) nicht aufzubrechen ist wenn z.B. genau in der Mitte eines Sektors etwas eingefuegt werden soll. Die Klassen aus den .NET kommen an dieser Gegebenheit nicht vorbei.Loesen wuerde ich das mit einer dritten Datei, wurde ja schon erwaehnt.
1. Du liest die Quelldatei byteweise aus, kopierst alles in die dritte Datei hinein, bis zu der Stelle, wo Du einfuegen moechtest.
2. Du liest die zweite Datei byteweise aus und haengst alles an die Dritte Datei am Ende an.
3. Du liest ab der Stelle von Pkt. 1 weiter aus und haengst alles an die dritte Datei weiter ans Ende an bis zum Schluss.
4. Du loeschst die Quelldatei.
5. Du benennst die dritte Datei um, sie bekommt den Namen der ehem. Quelldatei.Lass Dich nicht taeuschen, dass Texteditoren damit keine Probleme haben, denn sie koennen ohne Probleme Text ueberall einfuegen so viel wie Du willst. Ja, aber sie haben den gesamten Text auch im RAM, und beim Speichern wird alles immer neu geschrieben und Vorhandenes auf Festplatte ueberschrieben.
-
Hallo zusammen,
ich habe den Vorschlag aufgenommen und merge jetzt die beiden Dateien in eine dritte Datei.
Dabei bin ich auf ein neues Problem gestoßen.
Ich nutze einen FileStream und einen StreamReader, um die Quelldatei einzulesen.
Nun musste ich aber feststellen, dass die Funktion ReadLine des StreamReaders nicht die Position im FileStream updatet.
Dies scheint mir doch sehr komisch zu sein. Was mache ich hier falsch.
Anbei ein wenig Pseudocode, um den Sachverhalt zu erläutern:while(!EOF)
{
merke position via StreamReader.BaseStream.Position
ReadLine();
if (toInsert.compareTo(line)<1)
StreamReader.BaseStream.Position = gemerkte Position
FunktionWriteText();
}Also mein Problem ist eigentlich, dass ich immer eine Zeile im Voraus lesen muss, aber beim Einfügen vor der zuletzt gelesenen Zeile einfügen möchte.
Gruß