[C++/VC6] Low-level of C stream IO?

Pagina: 1
Acties:

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Ik ben bezig met het schrijven van een BitTorrent (een p2p file-sharing protocol) client. Momenteel gebruik ik C stream IO, maar recent ging dat fout omdat ik meer dan 512 files wilde openenen. Met _setmaxstdio heb ik dat verhoogd naar 2048.

Maar omdat files > 4 gb ook geshared moeten kunnen worden, wilde ik daarvoor ondersteuning inbouwen. Maar ik kan geen 64-bit versie van fseek vinden.

Er is wel een _lseeki64 voor low-level IO.
Is er gewoon geen 64-bit versie van fseek?

En is het enige verschil tussen low-level en C stream IO buffering en formatting?

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
De standaard C fseek neemt een long als filepointer, dus dat kan imho alleen op platformen waar een long 64 bits is.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

waarom niet gewoon met Win32 API?

CreateFile en daarna WriteFile/ReadFile, laatste 2 met met overlapped-struct als laatste paramater voor files>=4gb. (en SetFilePointerEx voor seek in grote files).

  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Er bestaat wel fsetpos en fgetpos onder windows. Dat werkt met __int64 ...
Edit: Dit zijn trouwens ANSI functies zie ik nu. In zn algemeenheid werken die met een fpos_t. In Visual C++ vertaalt dit echter naar een __int64

[ Voor 50% gewijzigd door SWfreak op 24-03-2004 14:51 ]


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Verwijderd schreef op 24 maart 2004 @ 14:27:
waarom niet gewoon met Win32 API?
Dat was ik vergeten te vertellen, maar ik wilde de code eigenlijk Linux-compatible houden.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
SWfreak schreef op 24 maart 2004 @ 14:50:
Er bestaat wel fsetpos en fgetpos onder windows. Dat werkt met __int64 ...
Edit: Dit zijn trouwens ANSI functies zie ik nu. In zn algemeenheid werken die met een fpos_t. In Visual C++ vertaalt dit echter naar een __int64
Remarks

The fgetpos function gets the current value of the stream argument’s file-position indicator and stores it in the object pointed to by pos. The fsetpos function can later use information stored in pos to reset the stream argument’s pointer to its position at the time fgetpos was called. The pos value is stored in an internal format and is intended for use only by fgetpos and fsetpos.
Volgens mij is dat dus ook niet zo'n goed idee.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 26-05 23:14
OlafvdSpek schreef op 24 maart 2004 @ 14:10:
En is het enige verschil tussen low-level en C stream IO buffering en formatting?
Dat zou ik niet kunnen bevestigen, maar ik denk het haast wel (ik kan geen ander voordeel van C-style I/O bedenken). Misschien doe je er dus verstandig aan om voor het lezen/schrijven van die bestanden gewoon de low-level functies (read, write, lseek, enzovoort) te gebruiken, zoals je al dacht. Ik neem aan dat je intern toch al redelijk wat aan buffering doet (ik neem bijvoorbeeld aan dat elk netwerkpakketje toch al minimaal kilobyte aan data bevat en dat je die niet byte voor byte gaat wegschrijven) en formatting heb je, denk ik, ook niet nodig. Low-level (POSIX-compliant) I/O is dan waarschijnlijk de beste oplossing in deze situatie; simpel, efficiënt en redelijk portable.

Verder zou je fgetpos/fsetpos kunnen misbruiken door aan te nemen dat ze voor binary files gewoon met 64-bits offsets werken (onder BSD is dat zo; onder Linux waarschijnlijk ook; onder Windows zou ik het niet weten), maar eigenlijk is dat natuurlijk niet echt netjes. Onder Windows is het enige moderne alternatief de Windows I/O functies te gebruiken, maar dat is dan weer niet portable. Overigens bestaat er ook een POSIX (.1) functie fseeko() als uitbreiding op fseek(), maar die wordt dus weer niet onder Windows ondersteund. Samenvattend lijkt het er dus op dat alleen de low-level I/O echt portable is.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Reads en writes zijn inderdaad tussen de 16 kb en 2 mb.
Ik had eigenlijk gelijk al low-level IO moeten gebruiken, maar ik had er helemaal niet aan gedacht.

[ Voor 4% gewijzigd door Olaf van der Spek op 24-03-2004 15:43 ]


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Deze functies zijn blijkbaar blocking en dat is niet zo handig. Is er een optie om ze non-blocking te maken?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 26-05 23:14
Vanwege dat andere topic kwam ik deze weer eens tegen. Met ioctl kun je je file descriptors normaal gesproken wel non-blocking maken, maar ik zou niet durven beweren dat dat onder Windows zomaar werkt.

[ Voor 34% gewijzigd door Soultaker op 01-04-2004 19:00 ]


  • cavey
  • Registratie: Augustus 2000
  • Laatst online: 17-02 19:31
om het trouwens portable te houden, kan je dan niet met #ifdef _WIN32 oid werken?
en zo bepaalde dingen in/excluden?

hmm, maakt je code op zich weer minder onderhoudbaar, als je hele tijd #ifdef secties moet maken in je routines.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Dat zou kunnen, maar als er functies zijn die zelf al portable zijn dan is dat natuurlijk veel makkelijker.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Soultaker schreef op 01 april 2004 @ 18:58:
Vanwege dat andere topic kwam ik deze weer eens tegen. Met ioctl kun je je file descriptors normaal gesproken wel non-blocking maken, maar ik zou niet durven beweren dat dat onder Windows zomaar werkt.
Ik hoopte dat Windows gewoon zelf de writes zou bufferen zonder dat ik daar speciale code voor nodig had, maar dat gaat blijkbaar niet altijd goed.

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

komakeef schreef op 02 april 2004 @ 11:53:
om het trouwens portable te houden, kan je dan niet met #ifdef _WIN32 oid werken?
en zo bepaalde dingen in/excluden?

hmm, maakt je code op zich weer minder onderhoudbaar, als je hele tijd #ifdef secties moet maken in je routines.
Ja dat is iets wat je als het even kan wilt vermijden... Ik heb het nu met mijn memory map wel, conditional include van een platform afhankelijke class, en dan met een typedef deze een standaard naam geven. Maar het punt is idd dat je dan elke wijziging al twee keer moet maken, en dat je code op een nieuw platform misschien al helemaal niet draait. Dan moet er contact met jou worden opgenomen om een nieuwe platform afhankelijke class te schrijven, dan moet je al je wijzigingen driee keer gaan maken. Met een beetje pech ondersteunt het nieuwe platform een specifieke call al helemaal niet, dus dan moet je alle drie de versies weer aanpassen...en niet vergeten moet je het steeds compilen en testen op elk platform... 8)7 |:( Nee, bedankt :)
Pagina: 1