Skocz do zawartości

Własny format pliku


Lunatyk

Rekomendowane odpowiedzi

W drugiej linijce powinno być f... ale to tylko mała korekta. Wszystko fajnie by było, gdyby nie to, że to nie posiada nagłówka pliku oraz wolałbym, żeby to było zapisywane bardziej po bajcie. Ja niestety jestem niezbyt doświadczony jeśli chodzi o pliki. Dzięki że zechciałeś pomóc, niestety nie skorzystam, chyba żebyś to zmodernizował.

 

@Tymon:

Możesz wyjaśnić co do tego typu danych? Bo ja chciałbym zapisywać coś jak rekordy w pascalu.

Odnośnik do komentarza
Udostępnij na innych stronach

Masz w sumie 3... 4 typy danych które mógłbyś przechowywać:

1. Liczby całkowite dodatnie

2. Liczby całkowite dodatnie i ujemne

3. Liczby zmiennoprzecinkowe

4. Tekst

Najłatwiej obsługiwać 1 i 4, nie wymagają jakichś zmyślnych metod przechowywania, pozostałem mogą Ci sprawić obecnie trochę problemów.

Odnośnik do komentarza
Udostępnij na innych stronach

Mala podpowiedz (ale pewnie glupia, bo co prawda ucze sie Pascala, ale byly tylko na zajeciach tekst i tablice):

is_real - sprawdza, czy dana jest liczba rzeczywista;

is_string - sprawdza, czy dana jest tekstem.

To tak á propos odczytywania.

Odnośnik do komentarza
Udostępnij na innych stronach

Dobra, to powoli pozbieramy Ci wszystko do kupy.

 

Wiesz, że pliki są przechowywane w postaci ciągu bajtów.

<bajt 1><bajt 2><bajt 3><bajt 4><bajt 5>...<bajtN>

Każdy bajt ma 8 bitów.

<bajt> = <bit 8><bit 7><bit 6><bit 5><bit 4><bit 3><bit 2><bit 1>

Tak, zapisywane są od prawej do lewej, a nie odwrotnie. Więc rozumiesz, że 2 bajty to 16 bitów, 3 to 24... itd.

 

Tego jak za pomocą 0 i 1 przechowywane są liczby w komputerze chyba nie muszę Ci tłumaczyć, prawda?

 

Kontynuując, jeden bajt może przechowywać za pomocą 8 bitów liczbę całkowitą dodatnią z zakresu 0-255.

Dwa bajty mogą przechowywać za pomocą 16 bitów liczbę całkowitą dodatnią z zakresu 0-65535.

Trzy bajty mogą przechowywać za pomocą 24 bitów liczbę całkowitą dodatnią z zakresu 0-16777215.

 

Można powiedzieć, że liczby w pamięci komputera są przechowywane w ten sam sposób jak i w plikach, ale w GMie nie masz dostępu do pojedynczego bajta pamięci, tylko do grupy bajtów i operujesz na tej grupie ( to ile ich jest zależy od typu zmiennej ), więc nie możesz po prostu przepisywać bajt po bajcie wszystkich danych, ale masz coś takiego jak operatory binarne które Ci pozwolą wyciągnąć konkretne bity z całego ich ciągu.

 

Tłumacząc to co będzie dla Ciebie najistotniejsze.

 

<< przesuwa bity w lewo o N bitów, tak więc przesuwając w lewo o 2 bity, bit 1 staje się bitem 3, a 2 5... itd.

0001101 ( 13 ) << 2 = 0110100 ( 52 )

>> przesuwa bity w prawo o N bitów, tak więc przesuwając w lewo o 2 bity, bit 3 staje się bitem 1, a 5 2... itd.

0001101 ( 13 ) >> 2 = 0000011 ( 3 )

& to coś jak logiczne i wykonywane bit po bicie

0001101 ( 13 )
0101001 ( 41 ) &
0001001 ( 9 )

| to coś jak logiczne lub wykonywanie bit po bicie

0001101 ( 13 )
0101001 ( 41 ) |
0101101 ( 45 )

 

Teraz konkretny przykład, masz liczbę zapisaną w postaci 24 bitów.

101010011101110101010111

I chcesz podzielić ją na 3 grupy po 8 bitów ( po bajcie ) czyli mniej więcej tak:

10101001 11011101 01010111

I każdą z tych grup zapisać do oddzielnego bita... jak to zrobić? Np. tak:

bajt 1
101010011101110101010111 >> 0 = 101010011101110101010111
101010011101110101010111 & 11111111 = 01010111

bajt 2
101010011101110101010111 >> 8 = 1010100111011101
1010100111011101 & 11111111 = 11011101

bajt 3
101010011101110101010111 >> 16 = 10101001
10101001 & 11111111 = 10101001

Masz wtedy zmienną 24 bitową ( 3 bajtową ) podzieloną na 3 grupy po 8 bitów ( po 1 bajcie ).

 

Pytania? Jeśli nie, to będę kontynuował.

Odnośnik do komentarza
Udostępnij na innych stronach

Tak.

 

To teraz prosty przykład zapisu w GMLu, będziemy zapisywać dowolną liczbę całkowitą dodatnią za pomocą 4 bitów:

GML
number = 242344563;

 

handle = file_bin_open( 'test.dat', 1 );

file_bin_write_byte( handle, ( number >> 0 ) & $FF ); // pierwsze 8 bitow

// zapis "X >> 0" można zastąpić po prostu "X" bo ">> 0" nic nie zmienia

// i jeszcze jedno, hex FF = dec 255 = bin 11111111

file_bin_write_byte( handle, ( number >> 8 ) & $FF ); // kolejne 8 bitow

file_bin_write_byte( handle, ( number >> 16 ) & $FF ); // kolejne 8 bitow

file_bin_write_byte( handle, ( number >> 24 ) & $FF ); // ostatnie 8 bitow

file_bin_close( handle );

Możesz ten proces powtarzać dowolną ilość razy i zapisywać w pliku po sobie dowolną ilość liczb całkowitych dodatnich.

 

KPW?

Odnośnik do komentarza
Udostępnij na innych stronach

Jest dokładnie tak jak mówisz, używa się wtedy tylko ord do zamiany znaku ASCII na liczbę.

 

GML
str = 'to testowy tekst';

 

handle = file_bin_open( 'test.dat', 1 );

for( i = 1; i <= string_length( str ); i += 1 )

file_bin_write_byte( handle, ord( string_char_at( str, i ) ) );

file_bin_write_byte( handle, 0 ); // bajt 0, zamykajacy string, najprostrza metoda pokazania programowi gdzie konczy sie string

file_bin_close( handle );

 

EDIT

Mała poprawka, w GMLu string zaczyna się od indeksu 1, a nie 0.

Odnośnik do komentarza
Udostępnij na innych stronach

No dobrze skoro już umiem zapisać liczby całkowite oraz tekst to jak je odczytać? Jak zauważyłem funkcja

GML
file_bin_read_byte
ma tylko jeden argument (uchwyt pliku) więc to tak jakby od razu czytał blok danych z pliku? Czy czyta bajty po kolei?
Odnośnik do komentarza
Udostępnij na innych stronach

Czyta tylko bajty.

 

Ale skoro masz 4 bajty które kolejno przechowują całą liczbę to możesz poskładać je w całość i uzyskać samą liczbę. Na przykładzie 3 bajtów:

bajt 1
01010111 << 0 = 01010111

bajt 2
11011101 << 8 = 1101110100000000

bajt 3
11011101 << 16 = 110111010000000000000000

liczba
                01010111 |
        1101110100000000 |
110111010000000000000000 =
110111011101110101010111

 

Odczyt do przykładu zapisu

GML
handle = file_bin_open( 'test.dat', 0 );

number = ( file_bin_read_byte( handle ) << 0 ) | ( file_bin_read_byte( handle ) << 8 )

| ( file_bin_read_byte( handle ) << 16 ) | ( file_bin_read_byte( handle ) << 24 );

file_bin_close( handle );

Odnośnik do komentarza
Udostępnij na innych stronach

GML
// zapis

handle = file_bin_open( 'test.dat', 1 );

 

// pierwsza liczba

number1 = 1234;

byte1 = ( number1 >> 0 ) & $FF; // wyliczamy 3 bajty

byte2 = ( number1 >> 8 ) & $FF;

byte3 = ( number1 >> 16 ) & $FF;

file_bin_write_byte( handle, byte1 ); // do pliku

file_bin_write_byte( handle, byte2 );

file_bin_write_byte( handle, byte3 );

 

// druga liczba

number1 = 5678;

byte1 = ( number1 >> 0 ) & $FF; // wyliczamy bajty

byte2 = ( number1 >> 8 ) & $FF;

byte3 = ( number1 >> 16 ) & $FF;

file_bin_write_byte( handle, byte1 ); // do pliku

file_bin_write_byte( handle, byte2 );

file_bin_write_byte( handle, byte3 );

 

file_bin_close( handle );

 

// odczyt

handle = file_bin_open( 'test.dat', 0 );

 

// pierwsza liczba

byte1 = file_bin_read_byte( handle ); // 3 bajty z pliku

byte2 = file_bin_read_byte( handle );

byte3 = file_bin_read_byte( handle );

number1 = ( byte1 << 0 ) | ( byte2 << 8 ) | ( byte3 << 16 ); // laczymy

// druga liczba

byte1 = file_bin_read_byte( handle ); // 3 bajty z pliku

byte2 = file_bin_read_byte( handle );

byte3 = file_bin_read_byte( handle );

number2 = ( byte1 << 0 ) | ( byte2 << 8 ) | ( byte3 << 16 ); // laczymy

file_bin_close( handle );

 

EDIT

Poprawiłem błąd, zapomniałem o uchwycie pliku. :P

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...