Daten an Datei anhängen (append) und Teil überschreiben



  • Hallo zusammen,

    hab i.M. gerade ein Problem, dass ich ich zwar Daten an eine bestehende Datei anhängen kann, aber ich bekomme es nicht hin, dass ein Teil der letzten Daten der geöffneten Datei überschrieben werden. Mittels "ftell" sehe ich zwar dass der Filepointer von 21 auf 10 zurückgeht, jedoch wird kein einziges Zeichen überschrieben sondern alles nach dem letzten Zeichen angehängt.

    Hat jemand eine Idee woran das liegt ?

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #include <iostream>
    #include <cstdio>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    using namespace std;
    
    TForm1 *Form1;
    
    FILE *fd;
    
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    // Ausgangsdatei C:\Temp\Text.txt erzeugen
    //
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
     char buffer[80], number;
     int count, temp;
    
     if ( (fd = fopen("C:\\Temp\\Test.txt", "w")) == 0 )
       {
    	ShowMessage("Fehler: Datei kann nicht erzeugt werden");
    	return;
       }
    
     number = 0x30;
     for ( count = 0; count < 20; count++ )
    	{
    	 buffer[count] = number++;
    	}
     buffer[count++] = '\0';
    
     temp = fwrite( buffer, sizeof(char), count, fd );
    
     fclose( fd );
    }
    //---------------------------------------------------------------------------
    
    // Daten anhängen und die letzten 11 Zeichen überschreiben
    //
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
     char buffer[80], number;
     long curpos;
     int count, result, temp;
    
     if ( (fd = fopen("C:\\Temp\\Test.txt", "a")) == 0 )
       {
    	ShowMessage("Fehler: Datei kann nicht geöffnet werden");
    	return;
       }
    
     result = fseek( fd, 0, SEEK_END );
     curpos = ftell( fd );                  // curpos == 21 == Dateiende
     result = fseek( fd, -11, SEEK_END );
     curpos = ftell( fd );                  // curpos == 10
    
     number = 0x30;
     for ( count = 0; count < 10; count++ )
    	{
    	 buffer[count] = number++;
    	}
     buffer[count++] = '\0';
    
     temp = fwrite( buffer, sizeof(char), count, fd );
    
     fclose( fd );
    }
    //---------------------------------------------------------------------------
    

    Danke und Gruß

    WoWe



  • Hallo WoWe!

    Wie ich sehe arbeitest du mit fopen und den zugehörigen Funktionen. Das habe ich zuerst auch so gemacht. Viel einfacher ist aber die Verwendung der TFileStream Klasse.

    Beispiel:

    char data[] = "hallo";    //Nur so ...
    TFileStream *f = new TFileStream("file.dat",fmOpenRead);    //Datei öffnen
    f->Seek(10,soFromBeginning);    //Lese- Schreibenzeiger 10 Byte nach Dateianfang
    f->Write(data,5);   //Etwas hineinschreiben
    delete f;   //Datei "freigeben", Wichtig!
    

    Fehlerüberprüfung ect. müsste man natürlich noch machen, aber meistens klappts ja. 😃
    Der Vorteil von TFileStream ist, dass alles gekapselt ist und der Code insgesamt leichter zu lesen ist.

    Warum dein Programm nicht funktioniert, kann ich auch nicht sagen. Eventuell beim schreiben explizit einen char* Pointer verwedenen der auf &buffer[0] zeigt.

    Gruß
    Markus



  • Ich nochaml,

    inzwischen habe ich mit deinem Quellcode etwas experimentiert. Die Lösung: Die Datei nicht mit dem Modus "a" sondern "r+" öffnen.
    Warum das mit "a" nicht funktioniert, ist mir allerdings auch nicht klar.

    Gruß
    Markus



  • Weil a für Append steht und das ist Englisch und heißt anhängen...

    Aus der Hilfe:

    Wert Beschreibung

    r Öffnet eine Datei ausschließlich für Leseoperationen.
    w Erzeugt eine Datei für Schreiboperationen. Falls die Datei bereits existiert, wird sie überschrieben.
    a Öffnet eine Datei für Schreiboperationen. Falls die Datei bereits existiert, werden weitere Daten an das aktuelle Dateiende angehängt, ansonsten wird sie automatisch erzeugt.
    r+ Öffnet eine Datei für Lese- und Schreiboperationen. Die Datei muß bereits existieren.
    w+ Erzeugt eine neue Datei für Lese- und Schreiboperationen. Falls die Datei bereits existiert, wird sie überschrieben.
    a+ Öffnet eine Datei zum Lesen und Anhängen neuer Daten durch Schreiboperationen. Falls die Datei bereits existiert, bleibt ihr alter Inhalt erhalten, falls nicht, wird sie automatisch erzeugt.



  • Hallo Markus,

    vielen Dank für deinen Tips. Das wars tatsächlich. Ich verstehe auch nicht warum append nicht funktioniert, ich möchte ja genau das tun, weitere Daten anhängen in der geöffneten Datei.

    WoWe



  • WoWe schrieb:

    anhängen in

    Genau da ist der Denkfehler. Es heisst Anhängen, nicht inhängen. 😉

    Vorgehensweise für's "Inhängen":
    - Puffer erstellen (Puffergrösse = Ursprungsdatei + Zusatzdatei - Überlappung)
    - Ursprungsdatei in Puffer laden/schreiben
    - fseek auf Anfang Überlappung
    - Zusatzdatei in Puffer schreiben



  • Jansen schrieb:

    Genau da ist der Denkfehler. Es heisst Anhängen, nicht inhängen. 😉

    Vorgehensweise für's "Inhängen":
    - Puffer erstellen (Puffergrösse = Ursprungsdatei + Zusatzdatei - Überlappung)
    - Ursprungsdatei in Puffer laden/schreiben
    - fseek auf Anfang Überlappung
    - Zusatzdatei in Puffer schreiben

    OK, Deine Erklärung Anhängen und eInhängen leuchtet mir ein, man muss halt nur mal drüber stolpern 🙂

    Aber bei der Vorgehensweise hab ich noch eine Frage: Das Beispiel von mir war mit kleinen Datenmengen, aber wenn es sich jetzt um große Datenmengen/Dateien handelt, wie funktioniert das dann mit dem Puffer ? Oder wenn die Größe der Zusatzdatei nicht bekannt ist (Daten werden im Programm erzeugt) ?



  • Da bietet sich doch eher TFileStream an, der agiert dynamisch.


Anmelden zum Antworten