fopen_s() liefert 0 zurück, FILE pointer ist aber Bad Ptr



  • Hallo,

    ich benutze folgenden Code um eine Datei zu öffnen:

    FILE* pBiqFile;
    errno_t ErrorNr;
    
    ErrorNr = fopen_s(&pBiqFile, argv[1], "rb");
    if (ErrorNr != 0) 
    {
      fputs ("File error",stderr); 
      exit (2);
    }
    

    Aktuell versuche ich, eine 2,5GB Datei zu öffnen, was mir aber nicht gelingt. Wie im Thread Titel schon geschrieben, ist ErrorNr nach dem Aufruf von fopen_s() 0, aber wenn ich mir pBiqFile anschaue, dann bekomm ich angezeigt, dass es ein Bad Ptr ist. Was ist da los?

    Ich habe es davor mit fopen() versucht gehabt, aber das ging genauso nicht. Liegt es an der Größe der Datei?

    Danke!

    Gruß

    Shinzo

    €: Kann auch eventuell ins WinAPI Forum verschoben werden, wobei ich wie gesagt denke, dass es nichts mit der API zu tun hat, da fopen() ja auch nicht geht.



  • Habe leider nicht wirklich viel Erfahrung mit fopen_s, aber was genau funktioniert denn mit fopen() nicht?



  • Habe das Problem wohl lokalisiert. Der FILE Pointer wurde zwar anfänglich vom Compiler immer als Bad Ptr deklariert, sobald man etwas gelesen hatte, ging es aber.

    Das Problem ist ftell(), dass ich etwas weiter unten benutze, um die Dateigröße zu bestimmen. Es gibt zwar einen long Wert zurück, allerdings hilft das nicht viel, denn long ist wie int auch nur eine 32-bit Variable. Da ftell() einem signed und leider kein unsigned long zurück gibt, begrenzt das die maximale Dateigröße auf 2GB. Daher kann ftell() mir nicht die Dateigröße zurückgeben und gibt mir deshalb -1 zurück. Ich dachte, dass es mir -1 zurück gibt, weil die Datei eben nicht richtig geöffnet werden konnte.

    Muss ich das Programm wohl doch in C++ schreiben. Hätte nicht gedacht, dass C solche Schwierigkeiten mit Dateien größer 2GB hat.



  • Du kannst aber immer noch auf die Funktionen des OS zurückgreifen, die mit Dateien > 2GB keine Probleme haben sollten.



  • Ist das dann noch C?

    Denn ich hatte C ja nur wegen der Performance verwendet.

    Jetzt schreibe ich das Programm gerade in C++ neu.

    Ich muss bei dem Programm double Werte einlesen (binär) und diese dann in Textform in eine .txt schreiben. Da das natürlich nicht gerade wenig Rechenaufwand braucht, kommt es da eben auf Performance an.

    Aktuell nehme ich den ofstream (operator<<) und schreibe den mit ifstream (read()) eingelesen Wert damit raus. operator<< ist natürlich leider nicht die schnellste Methode, aber es muss eben als ASCII in einer Textdatei stehen.



  • Also ich bin (noch :D) lange kein Experte auf diesem Gebiet und kann dir nicht sagen wo da C oder C++ schneller ist. Aber schneller als das OS selbst (->WinAPI) sollte wohl erstmal nix sein :xmas1:



  • RyoShinzo schrieb:

    Ist das dann noch C?

    Die gängigen Betriebssysteme bieten in diesem Zusammenhang eine reine C-Schnittstelle an.
    Wenn es um die WinAPI geht, sind die Begriffe CreateFile, ReadFile / WriteFile, SetFilePointer und CloseHandle.

    RyoShinzo schrieb:

    Denn ich hatte C ja nur wegen der Performance verwendet.

    Wie Cooky schon schrieb, brauchst du dir darüber keine Gedanken machen.

    RyoShinzo schrieb:

    Jetzt schreibe ich das Programm gerade in C++ neu.

    Auch mit C++ verwende ich eine RAII-Klasse, die mir das alles kapselt, also CreateFile im Kon-, CloseHandle im Destruktor ausführt und ggf. Teile der Datei sperrt. Binärdateien lese ich eigentlich fast immer mit Hilfe dieser Klasse.

    RyoShinzo schrieb:

    ..kommt es da eben auf Performance an.

    Bei diesen Lese- und Schreiboperationen dürfte der Zugriff auf die Festplatte der limitierende Faktor sein.



  • Bei der Systemleistung sehe ich, dass das System zu 50% ausgelastet ist. Da ich einen DualCore habe und meine Anwendung nur einen Core unterstützt, bedeutet das ja volle Systemauslastung.

    Wenn die Festplatte der limitierende Faktor wäre, dann dürfte die Systemleistung ja nicht komplett ausgelastet sein, oder?



  • Du könntest als ersten Schritt ja einmal die Kernel- und Userzeiten beobachten (beide tragen natürlich zur Auslastung bei).
    Die Kernelzeiten sollten bei dir wesentlich höher sein. Wenn du bswp. ein jpg oder png komprimierst, ist es normalerweise umgekehrt. Die Komprimierung ist recht aufwändig, zu schreiben gibt es im Verhältnis recht wenig.
    Aber bei einer reinen Umformung von doubles in Text? Ich weiß nicht.



  • fopen_s ist kein ANSI C.
    fopen_s ist eine MSVC Erweiterung und somit kein Standard.
    ftell liefert gemäß Standard einen long zurück, demzufolge ist die Größe der hiermit zu behandelnden Datei auf MAX_LONG begrenzt, bei 32-Bit Compilern also 2^31-1 = 2147483647 Bytes.
    Da du ja mit fopen_s schon den Weg der Nichtportabilität/Nichtstandard beschritten hast, warum gehst du ihn nicht weiter und verwendest die Nichtstandard-MS-CRT Funktion _ftelli64, anstatt mit deinen offensichtlich wenig fundierten C Kenntnissen hier Mutmaßungen über den C Standard anzustellen?



  • Danke für ftelli64(), das kannte ich noch nicht.

    Was hast du denn jetzt aber für ein Problem damit, dass ich versuche den Grund für den Fehler zu suchen?! Muss man ein Profi sein, wie du wohl bist, damit man sich Gedanken darüber machen darf, wieso ein Programm jetzt nicht funktioniert? Ich hatte doch recht damit, dass ftell() nur für Dateien mit maximal ~2GB benutzt werden kann. Also wo liegt jetzt dein Problem? Bist wohl als C Pro auf die Welt gekommen, oder wie? ...


Anmelden zum Antworten