Italia
Unità

FileClass - ab XProfan 8 Unit als Klasse incl. Source

 
Die erste Version meiner FileClass-Unit ist fertig

Bitte nicht mit der File-Unit verwechseln

Bisher ist die Auswahl an Klassen per XProfan ja noch ein bißchen dürftig, daher (und naturalmente aus personale Interesse) hab ich mich entschlossen eine FileClass zu erstellen. Diese Klasse kann fast beliebig viele File gleichzeitig erstellen, bearbeiten oder lesen (unabhängig von den Profan-internen Befehlen).
Alle Methoden (Funktionen in der Klasse) beruhen auf reinem Windows-API. Eine direkte Unterscheidung von Binär- und Textdateien gibt es nicht. Die Syntax ist auch sehr einfach.
Im beiligendem Source sind alle Methoden ausführlich beschrieben, desweiteren habe ich 3 Beispiele beigefügt, die einen Einstieg erleichtern sollten.
Die Unit soll, ich hoffe ja auch auf ein bißchen Teamwork, noch weiter ausgebaut werden. Einschränkungen zur Zeit: Fehlerbehandlung noch Stiefmütterlich
Geschwindigkeit bei Zeilenweise einlesen von Texten noch nicht so besonders (bisher ist noch keine Pufferung eingebaut).

Dateisystemfunktionen, also erstellen von Ordnern, ermitteln von Pfaden usw. sind nicht geplant. Die Klasse soll lediglich Dateioperationen ausführen. Selbstverständlich kann man später auch separat eine FileSystemClass erstellen, die bei Bedarf von dieser Klasse erbt

Saluto
Thomas
(ts-soft)
 $L
 $H windows.ph

{

    Class ?_File = -hFile&,
    -FileError&,
    +Error@,
    +Close@,
    +Create@,
    +Eof@,
    +Seek@,
    +Loc@,
    +Lof@,
    +Open@,
    +Read@,
    +GetFile@,
    +GetByte@,
    +GetWord@,
    +GetLong@,
    +GetFloat@,
    +GetString@,
    +GetData@,
    +PutByte@,
    +PutWord@,
    +PutLong@,
    +PutFloat@,
    +PutString@,
    +PutStringCR@,
    +PutData@,
    +Version@

}

################################################
# Erstellen, öffnen und schliessen von File #
################################################
Syntax: OBJEKT#.Create(FileName$)
Ergebnis: Handle des Files,
im Fehlerfall -1, OBJEKT#.Error wird auf TRUE gesetzt
Erklärung: Öffnet eine leere File. Existiert die angegebene File bereits,
wird diese geöffnet und durch eine leere ersetzt!!!

Proc ?_File.Create

    Parameters FileName$
    .FileError& = 0

    {

        .hFile& = ~CreateFile(Addr(FileName$),
        OR(~GENERIC_WRITE,~GENERIC_READ),
        0,
        0,
        ~CREATE_ALWAYS,
        ~FILE_ATTRIBUTE_NORMAL,
        0)

    }

    Case .hFile& = ~INVALID_HANDLE_VALUE : .FileError& = 1
    Return .hFile&

EndProc

Syntax: OBJEKT#.Open(FileName$)
Ergebnis: Handle des Files,
im Fehlerfall -1, OBJEKT#.Error wird auf TRUE gesetzt
Erklärung: Öffnet die angegebene File oder erstellt eine,
falls noch keine existiert. Du kannst nun Lese- und Schreibfunktionen in dieser File ausführen

Proc ?_File.Open

    Parameters FileName$
    .FileError& = 0

    {

        .hFile& = ~CreateFile(Addr(FileName$),
        OR(~GENERIC_WRITE, ~GENERIC_READ),
        ~FILE_SHARE_READ | ~FILE_SHARE_WRITE,
        0,
        ~OPEN_ALWAYS,
        ~FILE_ATTRIBUTE_NORMAL,
        0)

    }

    Case .hFile& = ~INVALID_HANDLE_VALUE : .FileError& = 1
    Return .hFile&

EndProc

Syntax: OBJEKT#.Read(FileName$)
Ergebnis: Handle des Files,
im Fehlerfall -1, OBJEKT#.Error wird auf TRUE gesetzt
Erklärung: Öffnet eine existierende File FileName$ ausschließlich per Lese-Operationen

Proc ?_File.Read

    Parameters FileName$
    .FileError& = 0

    {

        .hFile& = ~CreateFile(Addr(FileName$),
        ~GENERIC_READ,
        ~FILE_SHARE_READ,
        0,
        ~OPEN_EXISTING,
        ~FILE_ATTRIBUTE_NORMAL,
        0)

    }

    Case .hFile& = ~INVALID_HANDLE_VALUE : .FileError& = 1
    Return .hFile&

EndProc

Syntax: OBJEKT#.Close([File&])
Ergebnis: keins
Erklärung: Schließt die aktuelle File, welche damit nicht weiter benutzt werden kann
Wenn der optionale Parameter File& übergeben wird, wird diese File geschlossen, die
aktuelle File bleibt hiervon unbeeinflusst

Proc ?_File.Close

    If %PCount = 1

        Parameters file&
        ~CloseHandle(file&)

    Else

        ~CloseHandle(.hFile&)
        .hFile& = 0

    EndIf

EndProc

###############
# Daten lesen #
###############
Syntax: OBJEKT#.GetByte()
Ergebnis: gelesenes Byte
Erklärung: Liest ein Byte aus der aktuell geöffneten File ein

Proc ?_File.GetByte

    Declare temp1&, temp2#
    Dim temp2#, 1
    ~ReadFile(.hFile&, Addr(temp1&), 1, Addr(temp2#), 0)
    Dispose temp2#
    Return temp1&

EndProc

Syntax: OBJEKT#.GetWord()
Ergebnis: gelesenes Word
Erklärung: Liest ein Word aus der aktuell geöffneten File ein

Proc ?_File.GetWord

    Declare temp1&, temp2#
    Dim temp2#, 2
    ~ReadFile(.hFile&, Addr(temp1&), 2, Addr(temp2#), 0)
    Dispose temp2#
    Return temp1&

EndProc

Syntax: OBJEKT#.GetLong()
Ergebnis: gelesenes Long&
Erklärung: Liest ein Long aus der aktuell geöffneten File ein

Proc ?_File.GetLong

    Declare temp1&, temp2&
    ~ReadFile(.hFile&, Addr(temp1&), 4, Addr(temp2&), 0)
    Return temp1&

EndProc

Syntax: OBJEKT#.GetFloat()
Ergebnis: gelesenes Float!
Erklärung: Liest ein Float aus der aktuell geöffneten File ein

Proc ?_File.GetFloat

    Declare temp1!, temp2#
    Dim temp2#, 8
    ~ReadFile(.hFile&, Addr(temp1!), 8, Addr(temp2#), 0)
    Dispose temp2#
    Return temp1!

EndProc

Syntax: OBJEKT#.GetString()
Ergebnis: gelesene TextZeile als Text$
Erklärung: Liest einen String aus der aktuell geöffneten File,
bis ein End Of Line Zeichen gefunden wird. UNIX oder DOS

Proc ?_File.GetString

    Declare buffer#, bytesread&, Text$
    Dim buffer#, 1

    While ~SetFilePointer(.hfile&, 0, 0, ~FILE_CURRENT) < ~GetFileSize(.hfile&, 0)

        ~ReadFile(.hfile&, Addr(buffer#), 1, Addr(bytesread&), 0)
        Case Byte(buffer#,0) = 0 : break
        Case Byte(buffer#,0) = 10 : break
        Text$ = Text$ + Chr$(Byte(buffer#,0))

    EndWhile

    Dispose buffer#
    Return Translate$(Text$, Chr$(13), "")

EndProc

Syntax: OBJEKT#.GetData(MemoryBuffer&, LengthToRead&)
Ergebnis: keins (gelesene Bytes befinden sich im MemoryBuffer&)
Beschreibung: Liest den Inhalt der aktuellen File mit der
angegebenen Länge LengthToRead& (Anzahl zu einzulesender Zeichen)
in den angegebenen Speicherbereich MemoryBuffer& z.B. Adresse
einer Bereichsvariable

Proc ?_File.GetData

    Parameters MemoryBuffer&, LengthToRead&
    Declare buffer#
    Dim buffer#, LengthToRead&
    ~ReadFile(.hFile&, MemoryBuffer&, LengthToRead&, Addr(buffer#), 0)
    Dispose buffer#

EndProc

###################
# Daten schreiben #
###################
Die hier folgenden Methoden funktionieren nur,
wenn die File mit Schreib-Unterstützung geöffnet wurde
(entweder mit Create oder Open)
Syntax: OBJEKT#.PutByte(Wert&)
Ergebnis: keins
Erklärung: Schreibt einen Byte-Wert in die aktuelle File.

Proc ?_File.PutByte

    Parameters Number&
    Declare Temp#
    Dim Temp#, 1
    ~WriteFile(.hFile&, Addr(Number&), 1, Temp#, 0)
    Dispose Temp#

EndProc

Syntax: OBJEKT#.PutWord(Wert&)
Ergebnis: keins
Erklärung: Schreibt einen Word-Wert in die aktuelle File.

Proc ?_File.PutWord

    Parameters Number&
    Declare Temp#
    Dim Temp#, 2
    ~WriteFile(.hFile&, Addr(Number&), 2, Temp#, 0)
    Dispose Temp#

EndProc

Syntax: OBJEKT#.PutLong(Wert&)
Ergebnis: keins
Erklärung: Schreibt einen Long-Wert in die aktuelle File.

Proc ?_File.PutLong

    Parameters Number&
    Declare Temp&
    ~WriteFile(.hFile&, Addr(Number&), 4, Addr(Temp&), 0)

EndProc

Syntax: OBJEKT#.PutFloat(Wert!)
Ergebnis: keins
Erklärung: Schreibt einen Float-Wert in die aktuelle File.

Proc ?_File.PutFloat

    Parameters Number!
    Declare Temp!
    ~WriteFile(.hFile&, Addr(Number!), 8, Addr(Temp!), 0)

EndProc

Syntax: OBJEKT#.PutString(Text$)
Ergebnis: keins
Erklärung: Schreibt einen String in die aktuelle File

Proc ?_File.PutString

    Parameters Text$
    Declare Temp#
    Dim Temp#, Len(Text$)
    ~WriteFile(.hFile&, Addr(Text$), Len(Text$), Addr(Temp#), 0)
    Dispose Temp#

EndProc

Syntax: OBJEKT#.PutStringCR(Text$)
Ergebnis: keins
Erklärung: Schreibt einen String in die aktuelle File
und fügt ein EOL Zeilenumbruch hinzu

Proc ?_File.PutStringCR

    Parameters Text$
    Declare Temp#
    Text$ = Text$ + Chr$(13) + Chr$(10)
    Dim Temp#, Len(Text$)
    ~WriteFile(.hFile&, Addr(Text$), Len(Text$), Addr(Temp#), 0)
    Dispose Temp#

EndProc

Syntax: OBJEKT#.PutData(MemoryBuffer&, LengthToWrite&)
Ergebnis: keins
Erklärung: Schreibt den Inhalt des angegebenen Speicherbereichs
MemoryBuffer& mit einer Länge von LengthToWrite& in die aktuelle File.

Proc ?_File.PutData

    Parameters MemoryBuffer&, LengthToWrite&
    Declare buffer#
    Dim buffer#, LengthToWrite&
    ~WriteFile(.hFile&, MemoryBuffer&, LengthToWrite&, Addr(buffer#), 0)
    Dispose buffer#

EndProc

############
# Diverses #
############
Syntax: OBJEKT#.Error()
Ergebnis: 0 oder 1
Erklärung: Gibt im Fehlerfall True (1) zurück
Z. Zt. wird nur auf ~INVALID_HANDLE_VALUE bei
OBJEKT#.Create(), OBJEKT#.Open() und OBJEKT#.Read() geprüft

Proc ?_File.Error

    Return .FileError&

EndProc

Syntax: OBJEKT#.GetFile()
Ergebnis: Handle des Files
Erklärung: Hiermit kann auch nachträglich das
Handle der aktuellen File ermittelt werden

Proc ?_File.GetFile

    Return .hFile&

EndProc

Syntax: OBJEKT#.Eof()
Ergebnis: 0 oder 1
Erklärung: Hiermit ermitteln wir ob das Ende der
File erreicht wurde (1) oder nicht (0)

Proc ?_File.Eof

    Declare Result&

    If ~SetFilePointer(.hFile&, 0, 0, ~FILE_CURRENT) < ~GetFileSize(.hFile&, 0)

        Result& = 0

    Else

        Result& = 1

    EndIf

    Return Result&

EndProc

Syntax: OBJEKT#.Loc()
Ergebnis: Position
Erklärung: Gibt die aktuelle Zeiger-Position
innerhalb der File zurück

Proc ?_File.Loc

    Return ~SetFilePointer(.hFile&, 0, 0, ~FILE_CURRENT)

EndProc

Syntax: OBJEKT#.Seek(NewPosition&)
Ergebnis:
Beschreibung: Ändert den Lese/Schreib - Zeiger innerhalb
der File auf die angegebene NeuePosition. Dieser
Parameter muss in Bytes angegeben werden

Proc ?_File.Seek

    Parameters NewPosition&
    Return ~SetFilePointer(.hFile&, NewPosition&, 0, ~FILE_BEGIN)

EndProc

Syntax: OBJEKT#.Lof()
Ergebnis: FileSize
Erklärung: LOF steht per Length Of File (Länge der File).
Es gibt die Länge der aktuellen File zurück

Proc ?_File.Lof

    Return ~GetFileSize(.hFile&, 0)

EndProc

Syntax: OBJEKT#.Version()
Ergebnis: Version
Erklärung: Gibt die aktuelle Version
dieser Klasse als String wieder

Proc ?_File.Version

    Return "0.5.5.18"  Haupt-Version.Jahr.Monat.Tag

EndProc


10 kB
Hochgeladen:18.05.2005
Downloadcounter185
Download
 
13.05.2005  
 



Hab die Unit mal geupdatet.

OBJEKT#.UseFile(hFile&) wurde entfernt. Machte leider teilweise Probleme. Um mehrere File zu nutzen, ist es jetzt erforderlich per jede File eine neue Instanz der Klasse anzulegen. Erhöht zwar etwas den Schreibaufwand, aber es ist trotzdem weiterhin possibile fast beliebig viel File gleichzeitig zu bearbeiten.
Das Beispiel test3.prf wurde darauf angepaßt und auch gleich noch fehlerbereinigt.
Bei der vorigen Version, sind mir auf meinem System keine Fehler aufgefallen, lediglich Rolf teilte mir diese mit. Habs ja auch hoffentlich jetzt beseitigt. Ich bin also auf das Testen von euch angewiesen.

Saluto
Thomas
 
18.05.2005  
 



Habs kurz getestet und funzt gut.

Bei mir also Fehlerfrei.

Um nicht die Anzahl der Downloads jedes mal bei einem Update auf 0 zu setzen - nutze doch erst den Durchsuchen Knopf - und dann klicke auf neue Version.

Salve.
 
18.05.2005  
 



Hallo Thomas...

Bin leider (noch) kein XProfan Nutzer, deshalb werde ich erst mal auch nicht testen.
Bezogen auf ~Generic_write | ~Generic_read potuto dir aber da ein Profanbug evtl. mal etwas Probleme bereiten. Schau mal in Bugnity nach...
 
18.05.2005  
 



[quote:1382f2518b=iF]Habs kurz getestet und funzt gut.

Bei mir also Fehlerfrei.[/quote:1382f2518b]Das Freud mich erstmal
[quote:1382f2518b=iF]
Um nicht die Anzahl der Downloads jedes mal bei einem Update auf 0 zu setzen - nutze doch erst den Durchsuchen Knopf - und dann klicke auf neue Version.

Salve.[/quote:1382f2518b]
Habs wohl schon wieder verkehrt gemacht

[quote:1382f2518b=AH]Schau mal in Bugnity nach...
[/quote:1382f2518b]Hab die entsprechenden Stellen mit OR angepaßt

Saluto
Thomas
 
18.05.2005  
 




Rolf
Koch
Hi Thomas,

ja es geht jetzt!

Rolf
 
18.05.2005  
 



[quote:5439b97a2c]Schon wieder falsch gemacht[/quote:5439b97a2c]Gehe doch einfach mal in die Arena - dort kann man testen so viel man möchte.

Salve.
 
18.05.2005  
 




Michael
Wodrich
Nachfolgend eine Funktion mit Blockpuffer.
Proc ?_file.getstring

    Declare Buffer#, Bytesread&, Text$, Text2$, FSize&, aktPos&, found&
    Dim Buffer#, 1024
    FSize& = ~Getfilesize(.Hfile&, 0)
    aktPos& = ~Setfilepointer(.Hfile&, 0, 0, ~File_current)

    While aktPos& < FSize&

        ~Readfile(.Hfile&, Addr(Buffer#), 1024, Addr(Bytesread&), 0)
        Found& = MemPos(Buffer#,0,Chr$(0))

        If Found& <> -1

            Text2$ = String$(Buffer#,0)
            Text$ = Text$ + Text2$
            aktPos& = aktPos& + Len(Text2$) + 1
            ~Setfilepointer(.Hfile&, aktPos&, 0, ~File_Begin)
            Break

        EndIf

        Found& = MemPos(Buffer#,0,Chr$(10))

        If Found& <> -1

            Text2$ = Char$(Buffer#,0,Found&)
            Text$ = Text$ + Text2$
            aktPos& = aktPos& + Len(Text2$) + 1
            ~Setfilepointer(.Hfile&, aktPos&, 0, ~File_Begin)
            Break

        EndIf

        aktPos& = ~Setfilepointer(.Hfile&, 0, 0, ~File_current)

    Endwhile

    Dispose Buffer#
    Return Translate$(Text$, Chr$(13), "")

Endproc

 
Programmieren, das spannendste Detektivspiel der Welt.
23.12.2005  
 



Schön, das sich doch noch einer per diese Unit-Interessiert
Vielleicht sollte man den Buffer auf 4096 erhöhen, nur aus dem Grunde, weil der Wert in anderen mir bekannten Funktionen auch genommen wird. Ich denke mal das wird kein Zufall sein.

Frohe Weihnacht
 
23.12.2005  
 



Answer


Topictitle, max. 100 Zeichen.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Posting  Font  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Topic-Options

7.457 Views

Untitledvor 0 min.
Gast.081519.08.2024
Member 862464120.04.2024
Paul Glatz16.09.2018
Georg Teles16.01.2016
Di più...

Themeninformationen



Admins  |  AGB  |  Applications  |  Autori  |  Chat  |  Informativa sulla privacy  |  Download  |  Entrance  |  Aiuto  |  Merchantportal  |  Impronta  |  Mart  |  Interfaces  |  SDK  |  Services  |  Giochi  |  Cerca  |  Support

Ein Projekt aller XProfaner, die es gibt!


Il mio XProfan
Private Notizie
Eigenes Ablageforum
Argomenti-Merkliste
Eigene Beiträge
Eigene Argomenti
Zwischenablage
Annullare
 Deutsch English Français Español Italia
Traduzioni

Informativa sulla privacy


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie