MASM32-SDK (Dateizugriffe bei Windows Konsolapplikationen):
Die ganze Datei lesen und schreiben: InputFile und OutputFile

Dank der große Hauptspeichergröße ist es häufig möglich, eine Datei vollständig in den Speicher zu lesen, die gewünschten Änderungen auf den Speicherinhalt durchzuführen und das Speicherabbild der Datei wieder auf den Datenträger zu schreiben.

Die benötigte Speichergröße für das Lesen der Datei lässt sich vor ihrem Einlesen der Datei mit filesize) ermitteln. Für das Schreiben der Datei kann eine andere Größenangabe erforderlich sein. Das ist von den Änderungen abhängig.

Einfacher geht es mit InputFile und OutputFile. Diese beiden Makros beinhalten die komplette Behandlung der Datei einschließlich Öffnen, Lesen bzw. Schreiben und Schließen.

Das Testprogramm liest die Datei c:\temp\versuch.txt vollständig ein, schneidet bei jedem ihrer Sätze die beiden ersten Bytes ab und schreibt die verkleinerte Datei als c:\temp\versuch1.txt zurück.

Der letzte Testlauf des Programms Links:
Letzter Test des Programms mit einer zusätzlichen Sichtprüfung in hexadezimaler Darstellung.


Testprogramm Lesen und Schreiben vollständiger Dateien mittels InputFile und OutputFile
Hinweise zum Programm stehen unterhalb des Quellprogrammtextes
comment * ---------------------------
Testprogramm Lesen und Schreiben vollstaendiger Dateien
mittels InputFile und OutputFile.

    Gelesen wird c:/temp/versuch.txt
Geschrieben wird c:/temp/versuch1.txt

 mymasm32rt.inc - siehe fredriks.de/8086asm/masm321.php?f=2#mymasm32rt
 ----------------------------------------------- *
debugFT  equ FALSE
include  c:\masm32\include\mymasm32rt.inc
Main     PROTO           ;erforderlich weil Main eine Prozedur ist
.LIST
.data

;Defaultwerte
fname	db	'C:\temp\versuch.txt',0     ;Eingabedatei
lfname  equ $ - fname

fname1	db	'C:\temp\versuch1.txt',0    ;Ausgabedatei
lfname1 equ $ - fname1

satzanzahl   equ   50
satzlaenge1  equ   50
satzlaenge2  equ   48
flaenge2     equ   satzanzahl * satzlaenge2

countmodify  dword satzanzahl       ;fuer Schleifenzaehler

msg1    db  "Testprogramm Lesen und Schreiben vollst",ae,"ndiger Dateien",cr,lf
        db  "mittels InputFile und OutputFile.",cr,lf
        db  "    Gelesen wird c:/temp/versuch.txt",cr,lf
        db  "Geschrieben wird c:/temp/versuch1.txt"
crlf    db  cr,lf,0         ;Zeilenwechsel

 .code
start:
      invoke Main
      inkey
      invoke ExitProcess,eax

;-------------------------------
Main PROC
    LOCAL flen  :DWORD                  ;file length variable
    LOCAL hMem  :DWORD                  ;allocated memory handle

; -------------------------------------------------
; Oeffnet die Datei, legt den Datenpuffer an, liest die Datei und schliesst sie
; -------------------------------------------------
    mov hMem, InputFile(ADDR fname)
    mov flen, ecx                           ; Dateilaenge speichern

  DumpMem hMem, 100, "Anfang des Puffers vorher"

    mov     edi,hMem
    mov     esi,hMem
    inc     esi
    inc     esi

    mov     ecx,countmodify
    cld
;--------------
; schleife modify kuerzt den Satz um die ersten zwei Bytes
;--------------
modify:
    mov   countmodify,ecx
    mov   ecx,satzlaenge2/2
    rep   movsw           ;Uebertragung

;fuer den naechsten Durchlauf: edi passt, esi muss 2 Bytes vor
    inc   esi
    inc   esi

    mov   ecx,countmodify
    loop  modify

    test OutputFile(ADDR fname1,hMem,flaenge2), eax
    jnz @F
    print "Das Schreiben der Ausgabedatei ist fehlgeschlagen",13,10,0

@@:
  DumpMem hMem, 100, "Anfang des Puffers nachher"
    invoke StdOut,ADDR msg1             ;Anzeige Bedienungsanleitung
    ret
Main ENDP

; -----
; Unterprogramm Hinweistext ausgeben
; -----
help PROC
    print   offset  msg1
    mov     eax,0
    ret
help ENDP

 end start

Hinweise zum Testprogramm Lesen und Schreiben vollständiger Dateien mittels InputFile und OutputFile
mov hMem, InputFile(ADDR fname): InputFile öffnet die Datei, legt den Datenpuffer an, liest die Datei und schließt sie. Der Datenpuffer ist lokal innerhalb der Prozedur Main. Das bedeutet, er wird im Stackbereich angelegt.

mov flen, ecx: Die Sicherung der Dateilänge nach flen wird nicht benötigt.

cld: Das Löschen der Direction-Flag wird (vermutlich) nicht benötigt.

Schleife modify: Die Kürzungen der Datensätze erfolgt durch Kopieren der jeweils 48 rechten Bytes jedes 50 Bytes langen Datensatzes. Es ist möglich, den verkürzten Datensatz in den gleichen Speicherbereich zurückzuschreiben, da

  • der neue Satz nicht länger ist als der alte und
  • der Kopiervorgang in aufsteigender Adressierungsrichtung erfolgt, denn die Directionflag ist gelöscht.

mov ecx,satzlaenge2/2: Die zu übertragende Satzlänge (48 Bytes) ist gerade und somit ohne Rest durch 2 dividierbar. Dies ermöglicht die Nutzung der wortweisen Übertragung movsw mit der Hälfte der Schleifendurchgänge gegenüber der byteweisen Übertragung movsb.

Letztes Upload: 24.03.2023 um 11:35:16 • Impressum und Datenschutzerklärung