fread odczyt duzego pliku binarnego

0

Musze skopiować plik binarny, i mam problem bo nie odczytuje mi całego pliku tylko początek, aż do ustalonego bufora. Szukałem na forum, ale nie znalazłem rozwiązania mojego problemu.
Mój kod obecnie wygląda następująco:

			 FILE *plik, *plik1;
			 char *bufor, *buf[2];
			 int iResult = 0, bloki = 1, i = 0;
			 int wielkosc_pliku = 0;
			
			 plik = fopen("c:\\testy\\1.jpg","rb");
			 fseek(plik,0,SEEK_END);
			 wielkosc_pliku = ftell(plik);
			 fseek(plik,0,SEEK_SET);
			 bufor = (char*)calloc(BUFOR,sizeof(char));

			 if(wielkosc_pliku>BUFOR){
				 bloki = (wielkosc_pliku/BUFOR);
				 if((wielkosc_pliku % BUFOR)>0)
					 bloki++;
			 }
			 do{	
				 fseek(plik,BUFOR*i,SEEK_SET);
				 fread(bufor,sizeof(char),BUFOR,plik);
				 buf[i] = bufor;
				 i++;
			 }while(i<2);
			 fclose(plik);
	
			plik1 = fopen("c:\\testy\\temp1.jpg","wb");
			i=0;
			do{	
				 fseek(plik1,BUFOR*i,SEEK_SET);
				 bufor = buf[i];
				 fwrite(bufor,sizeof(char),BUFOR,plik1);
				 i++;
			 }while(i<2);

			fclose(plik1);

w pętli do while jest na stale i<2 ponieważ na razie plik sie nie zmienia.
Z góry dziękuje za pomoc

0
    fseek(plik,BUFOR*i,SEEK_SET);
    fread(bufor,sizeof(char),BUFOR,plik);

fseek nie jest tutaj potrzebny, po poczatkowym fseek(,0,..SET), kolejne fread'y beda czytac dane sekwencyjnie, kolejnymi blokami po 'BUFOR' elementow

   bufor = (char*)calloc(BUFOR,sizeof(char));
....
do{        
    fseek(plik,BUFOR*i,SEEK_SET);
    fread(bufor,sizeof(char),BUFOR,plik);
    buf[i] = bufor;
    i++;
}

alokujesz bufor RAZ, potem wskaznik do niego wykorzystujesz wiele razy do czytania z pliku, i wiele razu zapisujesz TEN SAM wskaznik do tablicy buf[]. w efekcie, po zakonczeniu petli, bedziesz mial sytuacje:
bufor = (np. char* 0x00AB1234) = [..dane z ostatniego bloku pliku..]
buf[] = { 0x00AB1234, 0x00AB1234, 0x00AB1234 ... }
rozumiesz w czym problem?

jesli chcesz skladowac kolejne kawalki/bloki pliku w pamieci, musisz na nie przygotowac oddzielne bufory, a nie wciaz jeden i ten sam, bo sobie nadpisujesz poprzednie dane..

jesli zas chcesz blokowo skopiowac plik na inne miejsce, w ogole NIE trzymaj wszystkich kawalkow pliku, a jedynie jeden aktualnie kopiowany blok:

  • utworz bufor
  • otworz plik1 do czytania
  • otworz plik2 do zapisu
  • w petli:
    --- czytaj N bajtow do bufora z pliku1
    --- zapisz N bajtow z bufora do pliku2
  • zamknij plik1
  • zamknij plik2
0

Problem rozumiem, ale w takim razie jak dynamicznie tworzyć kolejne bufory, tutaj mam prosta sytuacje bo działam ciągle na tym samym pliku i znam jego rozmiar, ale co gdy będę musiał działać na innym pliku?

Sorry, że tak kręcę, ale jestem początkujacy

A druga opcja z blokowym kopiowaniem niestety nie wchodzi w grę, plik najpierw musi być odczytany w całości a dopiero później zapisany.

0
1cichy napisał(a)

Problem rozumiem, ale w takim razie jak dynamicznie tworzyć kolejne bufory, tutaj mam prosta sytuacje bo działam ciągle na tym samym pliku i znam jego rozmiar, ale co gdy będę musiał działać na innym pliku?

W czym problem? Pierwszy bufor też zaalokowałeś dynamicznie, z kolejnymi zrobisz tak samo. Możesz je trzymać w pamięci w formie listy(tzn. każdy blok zawiera wskaźnik na kolejny blok).

1cichy napisał(a)

A druga opcja z blokowym kopiowaniem niestety nie wchodzi w grę, plik najpierw musi być odczytany w całości a dopiero później zapisany.

Fatalne rozwiązanie - skopiujesz tylko plik o wielkości niewiększej niż ilość dostępnej pamięci(a w tytule topicu piszesz, że chcesz kopiować duże pliki).

0

Dzięki za pomoc.
Ponieważ plik miał być wysyłany za pomocą funkcji send(), każdą porcje wysyłam od razu i nie problemu, nie muszę zapisywać nigdzie kolejnych buforów tak jak mówiliści.

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