Przenośne operacje na plikach powyżej 4GB

0

W jaki sposób wykonywać operacje na plikach powyżej 4gb, aby kod kompilował się zarówno pod windowsem jak i na linuxem?
Chodzi mi o podstawowe operacje: fopen, fread, fwrite, fseek, ftell. naraz do pamieci nie bede wczytywal wiecej niz ok. 100mb, jednak fseek zwraca wartosci 32bitowe (i na dodatek signed, czyli max 2GB) więc pojawia się problem w podróżach po pliku.

0

fseek przyjmuje chyba wartości względne wobec aktualnej pozycji w pliku. W ten sposób możesz skakać co 2 GB, aż dojdziesz do interesującego cię miejsca :P Nie wiem czy to zadziała, możliwe że wewnętrznie te funkcje używają 32-bitowych wartości i one się "przekręcą".

0

Na Linuksie otworzyłem dysk 120GB za pomocą fopen() i działo. Nie wiem, dlaczego? Ktoś wie?

0

na razie bede pracowac zeby przesuniecie w fseeku nie przekroczylo zakresu inta, jak cos nie bedzie dzialac to wtedy bede myslec

2

używaj fsetpos, fgetpos jeśli chcesz korzystać z dużych plików. Funkcja pobiera fpos_t do obsługi offsetu, i jest to typ, który gwarantuje, że ma zakres tak duży, jaki system operacyjny obsługuje. Dlaczego fseek działa ? Bo wewnętrzny wskaźnik na pozycję pliku to i tak system obsługuje, i takie żądania do systemu są delegowane. System daje radę - to mu nie przeszkadza, że sam fseek jest 32-bitowy.

Coby sobie sprawdzić, czy system obsługuje, to najprzenośniej by było jakoś tak pewnie...

#include <stdio.h>
 ... 
if( sizeof(fpos_t) > 4 ) ...
0

a czy fpos_t może być normalnie porównywany? (chodzi o określenie czy jakieś miejsce jest dalej w pliku czy wcześniej)

0

W MinGW z gcc 4.5.2 :

// stdio.h
/*
 * An opaque data type used for storing file positions... The contents of
 * this type are unknown, but we (the compiler) need to know the size
 * because the programmer using fgetpos and fsetpos will be setting aside
 * storage for fpos_t structres. Actually I tested using a byte array and
 * it is fairly evident that the fpos_t type is a long (in CRTDLL.DLL).
 * Perhaps an unsigned long? TODO? It's definitely a 64-bit number in
 * MSVCRT however, and for now `long long' will do.
 */
#ifdef __MSVCRT__
typedef long long fpos_t;
#else
typedef long	fpos_t;
#endif
0

czyli mozna ale nie koniecznie zwroci to prawidlowa odpowiedz?

0

jeśli chcesz to mieć "przenośne" w stylu super-duper-ansii-c to nie opieraj się na porównaniach < >, tylko i wyłącznie == != bo standard nie mówi w sumie czym to cholerstwo jest.

Na Windows można. Osobiście zawsze rzutuję to na typ całkowity i porównuję, dodaje, mnożę i dzielę.
Poza Windows - pojęcia nie mam.

Czy linuksowcy sobie fpos_t zaimplementowali jako "zwykły licznik", to już trzeba by w źródła im popatrzeć, bo w "duchu GNU", mogli swapnąć byte-order, przesunąć o 17 bitów w lewo, i pociągnąć xor'em z flagami bitowymi zawierającymi tryb dostępu do pliku ...

1 użytkowników online, w tym zalogowanych: 0, gości: 1