Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Was genau maches Dateibefehle? (https://www.delphipraxis.net/164862-genau-maches-dateibefehle.html)

iphi 3. Dez 2011 09:30

Was genau maches Dateibefehle?
 
Hallo,

ich möchte gerne genau verstehen, was die folgenden Dateibefehle machen:

1.
Delphi-Quellcode:
...
var
  F: Textfile;
...
AssignFile(F,'myfile.txt');
Hier wird der Variablen F irgendetwas zugewiesen, korrekt?
Wird hier dynamisch Speicher zugewiesen, der zu einem Memoryleck führen könnte, wenn das Programm nach diesem Befehl beendet wird?
Die Datei selbst wird hier noch nicht geöffnet, korrekt?
Noch könnten andere Programme in die Datei schreiben, korrekt?

2.
Delphi-Quellcode:
ReWrite(F);
Hier wird die Datei für Schreibzugriff geöffnet, korrekt?
Ab jetzt ist die Datei für andere Programme schreibgeschützt, korrekt?
Darf man rewrite mehrfach hintereinander ausführen?

3.
Delphi-Quellcode:
CloseFile(F);
Hier wird die Datei geschlossen und wieder freigegeben, richtig?
Passiert hier irgendwas mit der Variablen F?

himitsu 3. Dez 2011 10:06

AW: Was genau maches Dateibefehle?
 
Ich mach's mir Mal einfach ... schau doch selber nach ...
Grobe Zusammenfassung der Befehle/Typen:
Delphi-Quellcode:
const
{ File mode magic numbers }

  fmClosed = $D7B0;
  fmInput = $D7B1;
  fmOutput = $D7B2;
  fmInOut = $D7B3;

{ Text file flags        }
  tfCRLF  = $1;   // Dos compatibility flag, for CR+LF line breaks and EOF checks

type
  { Typed-file record }

{ Text file record structure used for Text files }
  TTextBuf = array[0..127] of AnsiChar;
  TTextRec = packed record (* must match the size the compiler generates: 720 bytes *)
    Handle: Integer; // FileHandle, wenn Datei geöffnet
    Mode: Word; // fmClosed..fmInOut
    Flags: Word; // Set of (tfCRLF, ...)
    BufSize: Cardinal; // = SizeOf(Self.Buffer)
    BufPos: Cardinal;
    BufEnd: Cardinal;
    BufPtr: PAnsiChar; // = @Self.Buffer[0] oder SetTextBuf
    OpenFunc: Pointer;  // OpenFile (Reset+Rewrite+Append)
    InOutFunc: Pointer; // Write/WriteLn/Read/ReadLn - Schreib/-Lesefunktion, je nach Self.Mode (Reset/Rewrite/Append)
    FlushFunc: Pointer; // Flush
    CloseFunc: Pointer; // CloseFile
    UserData: array[1..32] of Byte; // nicht verwendet
    Name: array[0..259] of Char; // dateiname
    Buffer: TTextBuf; // Lese-/Schreibpuffer
  end;

function AssignFile(var t: TTextRec; const FileName: PChar): Integer;
var
  Len: Integer;
begin
  FillChar(t, SizeOf(TFileRec), 0);
  t.BufPtr := @t.Buffer;
  t.Mode := fmClosed;
  t.Flags := tfCRLF * Byte(DefaultTextLineBreakStyle);
  t.BufSize := SizeOf(t.Buffer);
  t.OpenFunc := @TextOpen;
  t.Name := FileName;
end;

function OpenText(var t: TTextRec; Mode: Word): Integer;
begin
  if t.Mode <> fmClosed then CloseFile(t);
  ...
end;

function Reset(var t: TTextRec): Integer;
begin
  Result := OpenText(t, fmInput);
end;

function Rewrite(var t: TTextRec): Integer;
begin
  Result := OpenText(t, fmOutput);
end;

function Append(var t: TTextRec): Integer;
begin
  Result := OpenText(t, fmInOut);
end;

function CloseFile(var t: TTextRec): Integer;
begin
  Flush;
  t.Mode := fmClosed;
  Result := CloseHandle(t.Handle);
end;
AssignFile initialisiert den Record und setzt den Dateinamen
Reset/Rewrite/Append öffnen die Datei

1. Standardmäßig kann kein Speicherleck entstehen, außer man ruft AssignFile auf eine geöffnete Dateivariable auf.
Denn AssignFile kann den Status einer Datei-Variable nicht prüfen, vorallem wenn sie auch noch nicht initialisiert sein könnte.
Das Dateihandle bliebe dann geöffnet.

PS: Wird in WinNT und Nachfahren ein Programm beendet, würde Windows den Arbeitsspeicher (weitgehenst) aufräumen und Dateihandles schließen, selbst wenn noch was offen wäre.
Tipp: Selber ausprobieren? Datei öffnen ... fremdes Programm kann nicht lesen ... eigenes Programm abschießen (Taskmanager) oder Programm beenden und Datei dabei nicht schließen ... kann fremdes Program jetzt lesen?

2. Wie wäre es mal mit selber ausprobieren?
Nein, eigentlich nicht ... mehrere aufeinanderfolgene Offnenbefehle werden aber "ignoroert" (if open then exit).

3. Siehe Code.


PS:
TextFile = TTextRec (auch wenn man es so nicht gleich erkennt, aber man könnte es einfach mal casten)
File of ... = TFileRec
TFileRec = TTextRec ohne .Buffer und ohne .BufSize bis .BufPtr

iphi 3. Dez 2011 10:18

AW: Was genau maches Dateibefehle?
 
Danke für die Info!

Wie komme ich denn an system.pas? Bei meinem Delphi6 Personal sind nur die DCUs dabei.

Noch eine Frage zu Blockwrite:

Bei
Delphi-Quellcode:
ReWrite(F,size)
kann ich die Einheitsgröße des zu schreibenden Datenblocks über size einstellen.
Kann ich die Blockgröße unterwegs ändern ohne den Dateizeiger wieder auf den Dateianfang zu setzen, d.h. gibt es sowas wie
Delphi-Quellcode:
Append(F,size)
?
Bin in der Hilfe nicht fündig geworden.

fkerber 3. Dez 2011 10:22

AW: Was genau maches Dateibefehle?
 
Hi,

die Personal-Versionen erlauben leider keinen Zugriff auf den Source.
Der ist jeweils erst ab der Pro-Version dabei.


LG, Frederic

himitsu 3. Dez 2011 10:31

AW: Was genau maches Dateibefehle?
 
Zitat:

Zitat von iphi (Beitrag 1139053)
Wie komme ich denn an system.pas? Bei meinem Delphi6 Personal sind nur die DCUs dabei.

Indem man sich eine Professional oder höher kauft.

Die Size sollte kann (?) man nur bei einem "typelosen"
Delphi-Quellcode:
var f: File;
verwenden.
Bei
Delphi-Quellcode:
var f: File of XYZ;
wird automatisch SizeOf(XYZ) verwendet.

Blockwrite schreibt keine "Bytes" sondern "Count", also eine Mehrzahl an ganzen Blöcken, so wie es in der OH auch geschrieben steht.
geschrieben Bytes = Count * RecSize (RecSize z.b. siehe Parameter des Rewrite oder siehe File-Typ)

Du kannst also ein typloses File erstellen (RecSize = 1), bzw. ein
Delphi-Quellcode:
File of Byte
und dann über BlockWrite quasi die Bytes/Blockgröße angeben.
Ich würde hier aber eher zu einem Delphi-Referenz durchsuchenTFileStream raten.

PS: BlockWrite, Seek und Co. gibt es für Textdateien (TextFile) nicht.

Bjoerk 3. Dez 2011 10:33

AW: Was genau maches Dateibefehle?
 
BTW, himitsu, mit welchen Befehl kann man nochmal den Puffer vergrößern, hab’s vergessen ?

himitsu 3. Dez 2011 10:43

AW: Was genau maches Dateibefehle?
 
Zitat:

Zitat von Bjoerk (Beitrag 1139058)
BTW, himitsu, mit welchen Befehl kann man nochmal den Puffer vergrößern, hab’s vergessen ?

Das hatte ich "im" Quellcode mit erwähnt. :zwinker: BufPtr
Aber nur bei Textdateien ... die anderen haben keinen Puffer (abgesehn von der WindowsFileCache)

Bjoerk 3. Dez 2011 11:22

AW: Was genau maches Dateibefehle?
 
Okay, hab’s gefunden, die dazugehörige Procedure heißt SetTextBuf. Wo kommt eigentlich der Alias AssignFile her, in meiner System.pas steht nur _Assign?

himitsu 3. Dez 2011 11:29

AW: Was genau maches Dateibefehle?
 
Compilermagic ... du wirst dort auch kein Delphi-Referenz durchsuchenLength drin finden, sondern stattdessen z.b. soein komisches _LStrLen.

Die sind im Compiler verbaut und stehen quasi nur als Dummy in der System.pas drin.
Oder der Compiler baut entsprechende Umleitungen zur eigentlichen Funktion auf, inkl. eventueller Parameterkonvertierungen. (es gibt z.B. auch kein WriteLn mit mehreren Parametern)

Die System und SysInit darfst du also nicht immer wort-wörtlich interpretieren.

Bummi 3. Dez 2011 12:20

AW: Was genau maches Dateibefehle?
 
Nutzt man diese Dinosaurier eigentlich noch?

himitsu 3. Dez 2011 12:24

AW: Was genau maches Dateibefehle?
 
Ohne Nutzung von Fremdkomponenten, haben diese "bewährten" Proceduren auch ab und an mal ihre Vorzüge.
(vorallem bei ANSI-Textdateien oder mit Records)

hathor 3. Dez 2011 14:26

AW: Was genau maches Dateibefehle?
 
Google hilft - Korrekt?:
system.pas
http://www.google.com/codesearch#FKU...pas&ct=rc&cd=7

implementation 3. Dez 2011 14:39

AW: Was genau maches Dateibefehle?
 
Zitat:

Zitat von Bummi (Beitrag 1139076)
Nutzt man diese Dinosaurier eigentlich noch?

Wieso nicht? Nur weil sie alt sind, sind sie ja nicht schlecht.
Delphi-Quellcode:
System.Text
,
Delphi-Quellcode:
file of char
und
Delphi-Quellcode:
file of byte
nutze ich dauernd.
Sie stellen eine gute Methode dar, auf sprachintegrierte Weise auf Dateien zuzugreifen.
Ich sehe nicht, was daran schlechter sein soll als an
Delphi-Quellcode:
TFileStream
(außer vllt. Encoding und so'n Zeugs).

Bummi 3. Dez 2011 14:48

AW: Was genau maches Dateibefehle?
 
Um Logfiles zu schreiben habe ich es in einigen Modulen aus Faulheit drin gelassen, ansonsten bevorzuge ich inzwischen durchgehend Streams, vor allem da ich die Routinen so schreiben kann dass ich mir um die spätere Implementierung keine Gedanken machen muss. Also einmal schreiben und später verwenden für Memorystreams/FileStreams/"Verschlüssende Streams"/Pipes/TCP-IP etc.
Den wahlfreie Zugriff und die Typunabhängigkeit (Strings/Records/Serialisierungen etc.) hierbei sehe ich ebenfalls als Vorteil.

himitsu 3. Dez 2011 15:26

AW: Was genau maches Dateibefehle?
 
Zitat:

Zitat von hathor (Beitrag 1139088)
Google hilft - Korrekt?:

Du weißt aber, daß diese Dateien "illegal" und entgegen der Lizenzbedingungen dort gelandet sind?

implementation 3. Dez 2011 16:16

AW: Was genau maches Dateibefehle?
 
Zitat:

Zitat von Bummi (Beitrag 1139095)
da ich die Routinen so schreiben kann dass ich mir um die spätere Implementierung keine Gedanken machen muss. Also einmal schreiben und später verwenden für Memorystreams/FileStreams/"Verschlüssende Streams"/Pipes/TCP-IP etc.

OK, du hast mich überzeugt :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:08 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz