Dateigröße verändern



  • Hallo,

    wie kann ich unter Windows die Information, wie groß eine Datei ist verändern?

    Mein Problem ist, dass ich ohne den Systembuffer zu verwenden mit WriteFile aus der windows.h Dateien schreibe. Da ich ja nur Blocksize größen schreiben kann, wenn der Systempuffer aus ist muss ich Dateien, die eventuell kein vielfaches von der Blocksize als Größe haben, mit Zeichen auf das nächste Vielfache einer Blocksize auffüllen. Dafür verwende ich das Nullbyte ('\0'). Leider wird dies im Editor als Leerzeichen dann ausgegeben. Deshalb würde ich gerne den Eintrag im Dateisystem so verändern, dass ich die richtige größe der Datei angebe, so dass der Editor sieht, dass sie vor meinen Füllzeichen aufhört.

    Kann mir hier jemand helfen?

    Viele Grüße
    Tim



  • Wie bitte?
    Von welchen Blockgrößen redest Du?
    Die Blockgrößen welche ein Sektor hat, auf deren Elementen ein Dateisystem aufgebaut ist? Z.B. die Blockgröße 512 Bytes (bei FAT12 und FAT16) oder meistens 4096 Bytes (bei FAT32 und NTFS)

    AFAIK kannst Du mit WriteFile() ohne Probleme eine Datei mit beliebigen Byte-zwischengrößen auf ein Dateisystem (z.B. auf Festplatte) schreiben.
    Selbst wenn die Blockgröße ein Vielfaches 512 Bytes ist.

    Kann es sein, daß Du meinst, es wird erst geschrieben, wenn die entsprechende Blockgröße überschritten wird?
    Solange eine Datei noch geöffnet ist, ist nicht garantiert, daß alle Bytes bereits auf den Datenträger geschrieben sind!

    TimRoes schrieb:

    wenn der Systempuffer aus ist muss ich Dateien, die eventuell kein vielfaches von der Blocksize als Größe haben, mit Zeichen auf das nächste Vielfache einer Blocksize auffüllen

    Und warum mußt Du ein Systempuffer ausschalten?
    Du redest hier aber nicht von der Auslagerungsdatei (pagefile.sys)?
    Erklär mir mal kurz, warum Du das ganze so umständlich machst...



  • Das Schreiben ohne Systempuffer ist eine ne Vorrausetzung die ich habe.

    Also die Datei wird wie folgt angelegt:

    this->file = CreateFile(..., GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, [b]FILE_FLAG_NO_BUFFERING [/b], NULL );
    

    Wenn eine Datei mit dem Flag FILE_FLAG_NO_BUFFERING angelegt ist, kann ich per WriteFile nur vielfaches von 512Bytes schreiben, da es sonst mit einem Fehler abbricht.

    Und es handelt sich um eine ganz normale Datei, nichts mit pagefile.sys.



  • Ok, wenn das Deine Voraussetzung ist.
    Ich selbst habe das noch nie gebraucht, nicht mal bei seriellen Schnittstellen.

    Bitte verrate uns mal, welche Fehlermeldung Du da beobachtest?
    Und was sagt GetLastError() dazu?

    Hast Du die Informationen zu folgenden Seiten beherzigt?
    FILE_FLAG_WRITE_THROUGH and FILE_FLAG_NO_BUFFERING: http://support.microsoft.com/kb/99794
    File Buffering: http://msdn.microsoft.com/en-us/library/cc644950(VS.85).aspx
    CreateFile(): http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx

    Man beachte: FILE_FLAG_NO_BUFFERING does not affect hard disk caching or memory mapped files.

    Verwendest Du FlushFileBuffers() nach dem Schreiben?

    Martin

    P.S.: Ich bleibe dabei: Ein künstliches Auffüllen mit Nullbytes ist absoluter Schmarrn und eines guten Programmierers unwürdig.



  • Error Code 998 wird geliefert, wenn ich versuche Bytelängen zu lesen, die kein Vielfaches von 512 sind. Der Fehler verschwindet aber bei allen Vielfachen von 512 und das Schreiben klappt Problemlos.
    Dass das Auffüllen mit \0-ern Schmarn ist seh ich auch so, deshalb will ich ja die Dateigröße so anpassen, dass sie genau mit dem Inhalt auch übereinstimmt...
    Und in den Links hab ich auch nur das gefunden, was ich bisher gewusst hab, nämlich dass die Buffergrenzen, aus denen ich schreibe, passend zu den Blocksizes sein müssen, da sonst obriger Fehler ausgelöst wird.



  • Hallo,

    es gäbe da SetEndOfFile:

    http://msdn.microsoft.com/en-us/library/aa365531(VS.85).aspx

    MfG,

    Probe-Nutzer



  • Jetzt hab ichs:

    WriteFile() mit FILE_FLAG_NO_BUFFERING muß mit dieser Blockgröße erfolgen.
    D.h. Dir bleibt tatsächlich nichts anderes übrig, als auch den letzten Block in voller Blockgröße zu schreiben, selbst wenn nur noch 15 Bytes zu Ende zu schreiben wären.

    Nach dem der letzte Block geschrieben wurde, kürzt Du die Dateigröße:
    Du setzt vorher mit SetFilePointer() den Filepointer auf die entsprechende Stelle, dann rufst Du SetEndOfFile() auf, um die Datei dann endgültig auf die richtige Länge zu kürzen.

    Und zum Abschluß natürlich CloseHandle()...

    HTH,
    Martin



  • AFAIK muss man die Datei nochmal ohne FILE_FLAG_NO_BUFFERING öffnen um sie zu kürzen. Denn SetFilePointerEx funktoniert auch nur mit Vielfachen der Sektorgröße wenn die Datei mit FILE_FLAG_NO_BUFFERING geöffnet ist.



  • Joar genau so schauts aus.. Naja dann schau ich mal ob ich sie nochmal ohne öffnen darf oder ob ichs mit den NullBytes hinten lasse.

    Danke nochmal für die Hilfe.


Anmelden zum Antworten