[C++/Alg] Files >2GB

Pagina: 1
Acties:

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Topicstarter
Ik krijg het niet voor elkaar om onder XP/NTFS een file aan te maken die groter is dan 2GB... Ik werk nu al met FILE*, zodat ik fseek kan gebruiken die een long pakt, maar daar gaat het al mis. Die returned vrolijk een fout als ik verder dan 2GB seek. Ik kan er verder erg weinig concreets over vinden... Hoe kan ik dit het best aanpakken? Ook op een manier die onder *nix werkt.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

This function stores the file pointer in two DWORD values. To more easily work with file pointers that are larger than a single DWORD value, use the SetFilePointerEx function.

Professionele website nodig?


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Topicstarter
Dat is win32 (en had ik ook al gevonden), is er niet iets posix achtigs ofzo dat ook werkt? Ik test alleen op win32 het moet uiteindelijk op solaris draaien

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Zoijar schreef op 01 april 2004 @ 16:05:
[...]

Dat is win32 (en had ik ook al gevonden), is er niet iets posix achtigs ofzo dat ook werkt? Ik test alleen op win32 het moet uiteindelijk op solaris draaien
'Huge file' support is afaik op alle platforms API-specific. De posix interfaces dateren nog uit de tijd dat een 2Mb file hopeloos groot was he :)

Wat moet je uberhaupt met zo'n idioot grote file? * curry684 kan zich er behalve een DVD-image of database weinig bij voorstellen.

Professionele website nodig?


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Topicstarter
curry684 schreef op 01 april 2004 @ 16:11:
'Huge file' support is afaik op alle platforms API-specific. De posix interfaces dateren nog uit de tijd dat een 2Mb file hopeloos groot was he :)
Ja daar was ik al bang voor...misschien moet ik het maar opsplitsen in kleinere files/blocks... Ik creeer liever niet dit soort platform afhankelijkheid.
Wat moet je uberhaupt met zo'n idioot grote file? * curry684 kan zich er behalve een DVD-image of database weinig bij voorstellen.
16385x16385 (preprocessed) boom van hoogte data (12 bytes per entry)...eigenlijk wil ik ook nog wel 32769^2 en verder ondersteunen..12.8GB, 51.2GB, etc ;) Toch maar proberen op te splitsen in wat 768MB blokken dan.

  • Sjaaky
  • Registratie: Oktober 2000
  • Laatst online: 26-05 01:17
Zoijar schreef op 01 april 2004 @ 16:05:
is er niet iets posix achtigs ofzo dat ook werkt? Ik test alleen op win32 het moet uiteindelijk op solaris draaien
Tja dan kom je denk ik bij de Large File Summit uit. Maar of diezelfde calls onder windows werken? Ik zou het niet weten.

  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zoijar schreef op 01 april 2004 @ 15:37:
Ik krijg het niet voor elkaar om onder XP/NTFS een file aan te maken die groter is dan 2GB... Ik werk nu al met FILE*, zodat ik fseek kan gebruiken die een long pakt, maar daar gaat het al mis. Die returned vrolijk een fout als ik verder dan 2GB seek. Ik kan er verder erg weinig concreets over vinden... Hoe kan ik dit het best aanpakken? Ook op een manier die onder *nix werkt.
Een long is natuurlijk ook maar een 32 bits signed integer, die dus niet >= 2GB kan zijn :)
Probeer het eens met fsetpos (), die heeft een fpos_t (wat volgens mij iig een __int64 is op windows, ws. is het op Solaris ook een 64 bits int). Ook fsetpos () is een ANSI functie overigens :)

[ Voor 16% gewijzigd door .oisyn op 01-04-2004 16:54 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
.oisyn schreef op 01 april 2004 @ 16:51:
[...]


Een long is natuurlijk ook maar een 32 bits signed integer, die dus niet >= 2GB kan zijn :)
Probeer het eens met fsetpos (), die heeft een fpos_t (wat volgens mij iig een __int64 is op windows, ws. is het op Solaris ook een 64 bits int). Ook fsetpos () is een ANSI functie overigens :)
fpos_t is idd een __int64 onder Windows. Blijf echter wel uitkijken (ookal heb ik geen idee waar Olaf dit gevonden heeft. Ik kan het zo snel niet opgooglen)...

  • Yoeri
  • Registratie: Maart 2003
  • Niet online

Yoeri

O+ Joyce O+

(overleden)
SWfreak schreef op 01 april 2004 @ 17:28:
[...]


fpos_t is idd een __int64 onder Windows. Blijf echter wel uitkijken (ookal heb ik geen idee waar Olaf dit gevonden heeft. Ik kan het zo snel niet opgooglen)...
http://msdn.microsoft.com...lib/html/_crt_fgetpos.asp

& http://users.libero.it/ge.../linguaggioC/i_ofile.html

[ Voor 8% gewijzigd door Yoeri op 01-04-2004 17:32 ]

Kijkje in de redactiekeuken van Tweakers.net
22 dec: Onze reputatie hooghouden
20 dec: Acht fouten


Verwijderd

Zoijar schreef op 01 april 2004 @ 16:05:
Dat is win32 (en had ik ook al gevonden), is er niet iets posix achtigs ofzo dat ook werkt? Ik test alleen op win32 het moet uiteindelijk op solaris draaien
Dan zou ik llseek(2) gebruiken. Geen POSIX (helaas...), maar werkt wel op Solaris.

[ Voor 20% gewijzigd door Verwijderd op 01-04-2004 17:37 ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 26-05 23:14

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Topicstarter
Waar ik ook nu aan denk, waarschijnlijk kan ik het ook niet memory mappen, of wel? (mmap(), mapviewoffile()) Of is de address space wel 64bit? nee toch?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 26-05 23:14
Dat is platformafhankelijk. De IA-32 architectuur ondersteunt in principe 48-bits addressen sinds de 386, maar een gemiddelde applicatie (onder Windows, bijvoorbeeld) kan dat niet addresseren omdat in een flat model gewerkt wordt (en de 16-bits segment selectors dan dus niet gebruikt worden).

Mijn conclusie is hier trouwens hetzelfde als in de vorige thread: gebruik voor optimale portability de low-level file functions.

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Topicstarter
Soultaker schreef op 01 april 2004 @ 18:19:
Mijn conclusie is hier trouwens hetzelfde als in de vorige thread: gebruik voor optimale portability de low-level file functions.
En low-level is? Want dingen als fseek werken dus al niet, en zelfs als ik naar die llseek() kijk, dan zie ik al weer heel wat problemen. Zo kan je dan weer geen tell() gebruiken want die is dan wel weer ineens 32bits, net als read/write.

Ik heb eigenlijk al besloten het op te splitsen in 768MB blokken, of misschien nog wel kleiner. Maar in de toekomst zal ik ongetwijfeld nog eens large files nodig hebben, dus het is wel nuttig een goede oplossing te bespreken hier denk ik.

Vraag me af of we nog een keer een overgang mee gaan maken, van 64 naar 128 bit oid :) Kan het me nu niet voorstellen, maar het zal haast wel...

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 26-05 23:14
lseek is een POSIX functie. Onder Windows moet je waarschijnlijk nog steeds _lseeki64 gebruiken, maar dat valt nog wel met een simpele preprocessor definition op te lossen. lseek werkt alleen een filedescriptor (int) in plaats van op een FILE* en mist dus wat functionaliteit, vandaar de aanduiding 'low-level' (is misschien niet de juiste term).

  • AaroN
  • Registratie: Februari 2001
  • Laatst online: 16-08-2023

AaroN

JayGTeam (213177)

Met MapViewOfFile is dat geen probleem, daarmee kun je zelfs grotere files openen (Volgens Richter ;)).

Bijvoorbeeld:
code:
1
2
3
4
5
(PBYTE) pbFile = (PBYTE) MapViewOfFile(hMapFile, // handle to mapping object 
    FILE_MAP_ALL_ACCESS,               // read/write permission 
    0,                                 //  DWORD dwFileOffsetHigh,
    0,                                 //  DWORD dwFileOffsetLow,
    0);                                //  dwNumberOfBytesToMap

Als je dan in een loop bijvoorbeeld steeds een blok leest ten grootte van dwBytesInBlock
code:
1
2
3
SYSTEM_INFO sinf;
GetSystemInfo(&sinf);
DWORD dwBytesInBlock = sinf.dwAllocationGranularity;


Bijvoorbeeld:
__int64 qwFileOffset = 0;
en daarna natuurlijk qwFileOffset >> 32 voor de HighOffset en qwFileOffset & 0xFFFFFFFF voor de LowOffset.

Kun je door de hele file lopen. Moet je natuurlijk wel steeds de begin fileoffset verhogen met dwBytesInBlock ;)

Windows only helaasch :(

Zie ook : MSDN Example

[ Voor 26% gewijzigd door AaroN op 01-04-2004 19:28 ]

JayGTeam (213177)

Pagina: 1