File I/O unter Win32 mit C++
-
Hallo Volkard,
heist das, dass alles von mir Aufgezählte sind alte Zöpfe und werden in neuerem C++ nicht mehr verwendet bzw. gemieden ?
-
Hallo WoWe,
ich denke Deine herangehensweise ist nicht ganz korrekt. Zuerst must Du dir folgende Frage stellen:
1.)Benötige ich File I/O Handling für verschiedene Betriebssysteme ?
Wenn ja, dann sollte (muss) man sich mit dem zufriedengeben, was Standard C/C++ zur Verfügung (ist schon jede Menge) stellt und dabei berücksichtigen, dass es gerade bei den Filesystemen recht große Unterschiede zwischen UNIX(Linux) und Windows gibt.
2.)Arbeitest Du nur mit Windows dann nehmen das was Dir die jeweilige Klassenbibliothek (MFC,VCL,OWL) zur Verfügung stellt. Ist in der Regel sehr gut ausgetestet und nimmt Dir viel Arbeit ab. In bestimmten Situationen kannst Du immer noch entsprechenden API Aufrufe benutzen (Rechtestruktur bei NTFS, Netzwerklaufwerke usw.)
Memory mapping, wird wohl eher die Ausnahme als die Regel sein.
Was Geschwindigkeit angeht gibt es nach meiner Erfahrung z.Z. 3 Engpässe
1)
Netzwerk
Bsp. Datenbank eine Netzwerkkarte und z.B. 50 Abfragen. Die DB arbeitet Multithreaded eventuell sogar mit mehreren Prozessoren, erledigt die Abfragen sehr schnell und nun muss alles über eine LAN-Karte.
2)Festplatte (hat wenig mit de verwendeten Zugriffsmethoden sondern mit den entsprechenden Kontrollern und eben dem mechanischen Zugriff zu tun)
3.) Bei Datenbankanwendungen ungünstige SQL-Anweisungen
Also mit anderen Worten, eine allgemein gültige Antwort gibt es nicht !
Ich selbst verwende z.B. Streams wenn ich Methoden benötige, die in der Streamklasse enthalten sind.
Ich habe abe rauch keine Scheu mit einer TStringList Zeilen einer Textdatei einzulesen. Die Geschwindigkeit mit der das geschieht, wird garantiert durch meinen Festplattenkontroller bestimmt und nicht durch die Klasse TStringList !Gruß
Gerhard
-
Hallo Gerhard,
vielen Dank für deine ausführliche Antwort, aber ich glaube meine Frage ist nicht so richtig angekommen. Ich beziehe mich rein auf Windows und auf das Lesen und Schreiben von kleinen und großen binären Dateien, z.B. für einen Parser der eine TIFF Datei durchliest und interpretiert. Ich habe einen TIFF Interpreter/Converter geschrieben und finde ihn bei großen farbigen TIFF-Datei etwas langsam. Ich arbeite da mit FileRead und FileWrite und bin mir nicht sicher ob das die richtigen Methoden sind.
-
Was ist wichtiger für dich
Das deine Software portabel ist, dann nimm die Sachen die im C++ und in den guten C/C++ Beschreiben sind.
Willst du dich ganz auf MS$ einschworen nimm die Dinge aus der WinAPI
Wie CreateFile
Requirements
Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.Ich persönlich stehe eher auf portable Software als auf spezifische Lösungen. Das heißt ich teile die Progamme auf in Teile die
portabel sein sollen diese dann nach Standard, und Dingen die OS-Abhängig sind (Fenster und Mäuschenschupsen) die dann mit den OS-Api funktionen gelöst werden.Wir nutzen meistens diese Funktionen
fopen(), fread(), fwrite() ,fgets, fprintf,.FileRead(), FileWrite(),Habe aber für Sonderfälle z.B Shared Memory auf NT-Systemen CreateFile und ähnliches genutzt.
-
PAD schrieb:
Was ist wichtiger für dich
am besten portabel und schnell
Du sagst selbst ihr verwendet fread und FileRead, das habe ich auch schon in verschiedenen Programmen gemacht, aber mir ist noch kein Unterschied aufgefallen ob die eine oder andere Methode Vorteile oder Nachteile hat. Deswegen meine Frage hier in die Runde ob da schon jemand Unterschiede festgestellt hat, oder ist das so wie Opel fahren oder Ford fahren ?
-
WoWe schrieb:
Hallo Volkard,
heist das, dass alles von mir Aufgezählte sind alte Zöpfe und werden in neuerem C++ nicht mehr verwendet bzw. gemieden ?eher ja. aber gleich wird mir eh einer widersprechen und sagen, man müsse open() und close() benutzen, weil das schon immer so war.
ich behandle sie mal der reihe nach.
OpenFile() ist veraltet und nur noch aus kompatibilitätsgründen mit win3.11 vorhanden.
ReadFile() ist die winapi-funktion, um aus nem file zu lesen. schnell und unmittelbar. aber kein merklicher gewinn gegenüber ifstream und read.
auch kein gewinn. eher schaden, wenn FileWrite für alle paar bytes aufgerufen wird, statt selber wenigstens nen kleinen puffer zu haben.
CreateFile() ist die winapi-funktion, umd dateien zu öffnen und anzulegen. viele nette parameter. zum beispiel, daß temp-files beim schließen von selber verschwinden, zum beispiel, daß tempfile nicht ersat viel auf platte schreiben soll, zum beispiel ansage, daß sequentiell (oder random) gelesen wird, was angemessenere prefetching-strategie zur folge hat und noch so kram. daher für high-speed unverzichtbar.
_open(), _read(), _write(), _creat()
proprietär wie CreateFile und noch dazu wenig stark. lieber fopen()...
typische c-schnittstelle. durch <fstream> völlig verdrängt.
ja, wenns das framework verlangt.also weil CreateFile() so stark ist, nehm ichs gerne. lohnt sich aber nur, wenn dabei gleich ein filemapping ist und vielleicht auch ein kleiner verzicht auf string und locale. anderenfalls ist kein speedvortiel zu fstream bemerkbar.
normalerweise fstream.
wenn schon winapi, dann nur mit wrapper drum, der einerseits beim destruktor auch aufräumt und andererseits leicht - an genau einer stelle, statt überall im programm verteilt - nach linux oder ein anderes gutes bs portierbar ist. linux kann memory-mapping, also kannste diesbezüglich in die vollen greifen.
-
Tschuldigung
Habe noch nie FileRead(), FileWrite()benutzt, kann es auch nicht in MSDNm Onlinehilfe und C/C++ Büchern finden
Wo gibts das
-
Hallo WoWe,
ich denke mal, dass FileRead und FileWrite in sich schon sehr schnell sind (liest direkt in eine Buffer ein, was sollte da schneller sein). Eventuell kannst Du einen Test mit einer Streamklasse (TMemorystram) machen. Ob es wirklich was bringt, kann ich Dir nicht sagen. Das eigentliche Problem wird die Festplatte und der Kontroller sein (IDE,SCSI) ggf. falls Du alles über das Netzwerk machst, natürlich auch das LAN.
Was Portabilität angeht, kann ich Dir nur eines sagen:
Wenn Du Windowsprogramme entwickelst, dann nutze die Fähigkeiten von Windows !
Nur ein kleiner spezieller API-Aufruf macht Deine Portabilität zunichte. Der Traum von Prgrammen, die auf allen Plattformen laufen wird schon ewig geträumt. Die Realität sieht anders aus (Nun kommt mir bloß nicht mit Java).
Und auch das standardisierte C++ wird eben nicht von allen C++ Compilern richtig verstanden bzw. umgesetzt(Der ewige Streit "Unser Compiler entspricht dem Ansii Standard")Gruß
Gerhard
-
WoWe schrieb:
Hallo Gerhard,
einen TIFF Interpreter/Converter geschriebentiff sind immer kleiner als 2GB. und man mag die daten sehr roh anfassen. so richtige char-zeiger rin ins gemüse. und dann nen kleinen bitweise-leser. und richtig schnell soll es auch sein. also da ist memory mapping direkt verpflichtend.
-
PAD schrieb:
Wo gibts das
Ich denke das ist Bestandteil der VCL
Du sagst FileOpen und OpenFile bzw. FileRead und ReadFile in einem Zusammenhang. Das sind doch 2 paar Schuh (VCL und API)